我想检查给定的Class是否可以赋值给java.util.Collection,如果是,则创建一个新的实例。
我尝试了以下内容:
Class<?> clazz = ... // I got this from somewhere
if (!clazz.isInterface() && java.util.Collection.class.isAssignableFrom(clazz)) {
java.util.Collection<?> collection = clazz.newInstance();
}
可以预见它不起作用,因为它无法转换为java.util.Collection的未知类型。 我想添加一个演员,但这似乎是一个黑客。
我也想过这样做:
Class<? extends java.util.Collection<?>> collectionClass = Class<? extends java.util.Collection<?>> clazz;
java.util.Collection<?> collection = clazz.newInstance();
现在没有必要在newInstance进行强制转换,但我仍然需要强制转换Class对象。
这样做的正确方法是什么?感谢。
(为了清楚起见,我在newIstance中删除了try / catch,以防我试图实例化一个抽象类)
答案 0 :(得分:3)
由于你使用的外卡,必须使用Cast。即Class<?> clazz
。铸造不是黑客,来吧。在这里它相当精细,因为它在检查下。
答案 1 :(得分:0)
当你使用newInstance()时,你必须使用强制转换。你的第一个例子很好。
答案 2 :(得分:0)
这是一个有趣的问题。第二种形式避免了对调用clazz.newInstance()
的结果进行显式类型转换的需要。实际上,发出的代码将包含一个隐式类型转换,因为编译器不知道newInstance()
方法是否作弊(做“不安全转换”)并返回错误类型的内容。
答案 3 :(得分:0)
尝试clazz.asSubClass(Collection.class).newInstance()
,这应该会给出一个已经输入Collection<?>
个实例
答案 4 :(得分:0)
在if语句之后,你知道clazz是集合的子类(即使compilr不知道)。所以你可以施展它:
Class<?> clazz = ... // I got this from somewhere
if (!clazz.isInterface() && java.util.Collection.class.isAssignableFrom(clazz)) {
Class<Collection<?>> collectionClazz = (Class<Collection<?>>) clazz;
java.util.Collection<?> collection = collectionClazz.newInstance();
}
编译器会抱怨在运行时没有检查强制转换(因为在运行时缺少泛型参数),但没关系。
...刚看到“asSubclass”方法。做同样的工作,但是在运行时检查它 - 它重做你的if()所做的测试。
话虽如此 - 每当我看到关键字instanceof时,我立即怀疑应该使用泛型类型。也就是说,包含上述代码的类或方法应该可以访问参数化类T并使用Class。