I have been reading the answers to the question:
Create instance of generic type in Java?
I have implemented the approach suggested by Lars Bohl. I adapted his code as follows:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class ParameterizedTypeEg<E> {
public Class<E> getTypeParameterClass() {
Type type = getClass().getGenericSuperclass();
ParameterizedType paramType = (ParameterizedType) type;
return (Class<E>) paramType.getActualTypeArguments()[0];
}
private static class StringHome extends ParameterizedTypeEg<String> {
private String _string;
StringHome (String string) {
_string = string;
}
}
public static void main(String[] args)
throws InstantiationException, IllegalAccessException {
String str = new StringHome("my string").getTypeParameterClass().newInstance();
String str2 = new ParameterizedTypeEg<String>().getTypeParameterClass().newInstance();
}
}
This approach works fine for the str variable. Then str2 is created with what appears to me to be the same type (ParameterizedTypeEg < String >, which is basically the same thing as a StringHome). However, the approach does not work for str2, and a ClassCastException is thrown when I try to cast (ParameterizedType) type.
Even though for str2, I have parameterized ParameterizedTypeEg with a String, getGenericSuperclass() returns something very different than for str. Also, within methods str2 shows 'this' as a ParameterizedTypeEg, whereas for str, 'this' is a ParameterizedTypeEg$StringHome. I suppose that is the root of the problem. Why does Java not see that the generic type has been determined for str2 also?
I have had what appears to be the same problem when the parameterized type is passed through multiple levels of hierarchy? That is, class B< T > contains A< T > and I instantiate a B. Within A, I cannot create a String object by determining the parameterized type of A using the above approach. The approach produces an exception in the case of a containment hierarchy as well. And this causes me a problem because I want to be able to pass the parameterized type through multiple levels of containment and/or inheritance and have the same approach produce an instance of the generic type in all cases.
Thanks, John