实例化可分配给Collection的类

时间:2009-12-16 09:48:29

标签: java generics

我想检查给定的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,以防我试图实例化一个抽象类)

5 个答案:

答案 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。