我一直在阅读问题的答案:
我已经执行了Lars Bohl建议的方法。我对他的代码作了如下修改:
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();
}
}
这种方法对于str变量很好。然后创建str2,其类型在我看来是相同的(ParameterizedTypeEg < String >,这与StringHome基本上是一样的)。但是,这种方法不适用于str2,当我尝试强制转换(ParameterizedType)类型时,会引发ClassCastException。
即使对于str2,我已经用字符串参数化了ParameterizedTypeEg,但是getGenericSuperclass()返回与str非常不同的内容。此外,在方法中,str2将'this‘显示为ParameterizedTypeEg,而对于str,'this’是参数化的this$StringHome。我想这就是问题的根源。为什么Java没有看到泛型类型也是为str2确定的?
当参数化类型通过多个层次结构传递时,我遇到了相同的问题吗?也就是说,类B< T>包含A< T>并且我实例化了B。在A中,我不能通过使用上述方法确定参数化A的类型来创建字符串对象。这种方法在包含层次结构的情况下也会产生异常。这给我带来了一个问题,因为我希望能够通过多个级别的包容和/或继承传递参数化类型,并且在所有情况下都使用相同的方法生成泛型类型的实例。
谢谢,约翰
发布于 2013-08-31 21:12:58
通过以下更改,您的代码将工作:
从…
String str2 = new ParameterizedTypeEg<String>().getTypeParameterClass().newInstance();
至
String str2 = new ParameterizedTypeEg<String>(){}.getTypeParameterClass().newInstance();
这将创建一个匿名的ParameterizedTypeEg子类。当你打电话的时候
getClass().getGenericSuperclass();
在StringHome上,您将得到一个ParameterizedTypeEg < java.lang.String>,这正是您想要的。如果您像以前一样创建str2,则该调用只返回对象,因此将其转换为paremeterized的尝试失败:
线程"main“java.lang.ClassCastException中的异常:不能将java.lang.Class转换为java.lang.reflect.ParameterizedType
创建匿名子类使返回ParameterizedTypeEg < java.lang.String>
这与Google库中的类型标记类使用的技巧相同。例如,你写
new TypeToken<List<String>>() {}
而不是
new TypeToken<List<String>>()
发布于 2013-08-31 20:54:37
getClass().getGenericSuperclass();
向您提供了超类的详细信息。因此,只有在子类为参数化超类时,它才能工作。如果实例化给定类型参数的参数化超类,它将无法工作。
发布于 2013-08-31 21:14:17
但是,该方法不适用于str2,当我尝试强制转换(ParameterizedType)类型时,会引发ClassCastException .为什么Java没有看到泛型类型也是为str2确定的?
如oracle中为ParameterizedType指定的
ParameterizedType表示参数化类型(如
Collection<String>
)。
但是,ParameterizedTypeEg
的超类是对象,而不是泛型类型。因此,由Type
返回的getClass().getGenericSuperclass();
是对象本身的Class
。对ParameterizedType
的非参数化类型的类型转换是为str
提供ClassCastException
。
https://stackoverflow.com/questions/18555122
复制