我对泛型有疑问。
我有一个函数,它知道我想要创建的类对象类型:
public static <T> XmlParserInterface<T> createXmlParser(Class<T> rootType, String currentTagName) {
XmlParserInterface<T> result = null;
if (rootType.equals(List.class)) {
result = new XmlParserList<T>();
}
// ...
result.init(rootType, currentTagName);
return result;
}
在该功能中,对于此特殊情况,我将rootType
称为List<String>
。
在我的init
函数中,我再次传递rootType
,以便创建ArrayList<something>
。我的问题是找到something
,因为我需要它来生成更多的对象。在这种情况下,它会是String
,但它可以更深入地成为List<List<String>>
甚至自定义POJO,我会检查它们的set
函数来填充它们。
我尝试过rootType.getTypeParameters()[0]
,但它只返回E
。我需要知道E
的实际类。
感谢所有人都能回答:)
答案 0 :(得分:1)
唉,这些信息在运行时是不可用的,Java会通过擦除过程抛弃这些信息。因此,唉,你想做的事情是不可能的。
答案 1 :(得分:1)
您需要显式添加类型信息 - 它在运行时不可用,因为在编译期间删除了泛型类型参数。因为你需要明确地指定它,所以你只能使用泛型来做你想做的事情(据我所知)。相反,你需要进行一些转换(并传递某种类型的结构,表明你想要构建什么)。
请参阅Wadler关于Java Generics的优秀书籍(如果你想编写这样的代码,你真的需要购买和阅读这本书。)
如果你一直有,请说List&lt; X&gt;然后你可以这样做(你仍然需要扩展签名,但代码将编译而没有任何类型的警告)。或甚至X&lt; Y&gt;其中X本身就是一个变量,比如子类List。你不能做的是处理X&lt; Y&gt;和X&lt; Y&gt;&gt;而不强迫系统进行“不安全”的操作。
X&lt; Y&gt;案例看起来像:
public <Y, X extends List<Y>> X<Y> myMethod(Class<X<Y>> xClass, Class<Y> yClass, ...) { ...}
(这只是来自记忆,但你可以得到这个想法,我希望 - 你传递X和Y,你使用合格的类型注释来表达它们之间的关系。真的,阅读Wadler的书!)。
如果你想手动强制执行,你必须只传入一个没有类型的Class值列表,并添加大量的转换。