Reputation: 672
I created a factory interface for some other generic interface A<T>
:
public interface Factory<T, X extends A<T>> {
public X create();
}
Now i have the problem that i need to instantiate a factory for every single type T. This becomes very unhandy, especially if some code wants to do some transformation from A<T>
to A<T2>
, where T2 is some previously unknown type or there are so many different T2, that i do not want to specify hundreds of factories for each special case.
I would like to pass the type T as a generic parameter of the create method. Such that i get something like (Attention, not correct Java :-) ):
public interface Factory<X extends A<?>> {
public <T> X<T> create();
}
An implementation of Factory might then simply do something like:
public class Factory4B implements Factory<B> {
public <T> X<T> create() {
return new B<T>();
}
}
Writing the above version of the interface down gives the error message for the return value of create:
The type X is not generic; it cannot be parameterized with argument
Is there some way to realize such a generic factory, or do i need to use a totally different approach? I want to be able to specify X at the class level, such that i can instantiate X easily. I do not want to create a single Factory for every parameter T
Thank you for your time to answer this question in advance.
Rethinking the problem based on the comments below, my question is not possible to realize as it is not possible to guaranty that the generic parameters are still present in the subclasses of A<T>
, or in other words: there is no inheritance of generic parameters.
Example:
A<String>
. C<Integer>
as C has no type argument. C<Integer>
Upvotes: 5
Views: 1712
Reputation: 12932
No, this is not possible with generics alone. Due to "type erasure" the type of T
is not there anymore at runtime, so Java doesn't know what constructor to call.
You'll have to find a way to pass the type of T
to your class at runtime. In, Java you can use the class Class<S>
as a runtime type token. Then your code might look something like this:
public <T> X<T> create(Class<T> classOfT) {
T t = classOfT.newInstance();
return new X<T>(t);
}
Upvotes: 3