如何使用有效的泛型声明Class.class

时间:2011-05-19 23:33:49

标签: java generics nested-generics

注意:完全出于好奇而不是任何实际用例。

我想知道是否有办法用有效的类型参数声明Class Class对象:

Class cc1 = Class.class; //raw type
Class<Class> cc2 = Class.class; //now parameter is raw type
Class<Class<?>> cc3 = Class.class; //compile error: inconvertible types

如果ClassClass<?>可以互换,为什么Class<Class>Class<Class<?>>不可以?

编辑:这个问题可以推广到嵌套原始类型参数的问题。例如:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList>(); //same compile error

EDIT2:我应该稍微改一下这个问题:我知道

Class<?> c = Class.class;

有效,但我想知道为什么Class<Class>Class<Class<?>>不一样

3 个答案:

答案 0 :(得分:2)

很难确切地看到你在问什么(或者你正在尝试做什么)..但你可以在没有原始类型的情况下进行参数化。

Class<? extends Object> cc4 = Class.class; // no raw types
Class<?> cc5 = Class.class; // also an option

就你的上一个例子而言,它没有任何意义,因为看起来你想要创建一个包含?的数组列表的数组列表,但你的声明并没有声明一个数组列表的数组列表持有?

正确编写(但仍然不合适的Java)将是:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<Integer>>(); // Type mismatch

预期。由于以下原因不起作用,它不起作用:

Object o = new Object();
Integer i = new Integer(3);

o = i;
i.floatValue();
o.floatValue(); // can't access that method, we need to specifically cast it to Integer

不主动推断Java类型(即使在继承链中)。

如果你想保留通配符,欢迎你,但是:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<?>>(); // works!

答案 1 :(得分:2)

此处的规则是左侧的泛型类型必须与右侧的泛型类型匹配。

Class<?>表示任何类型的类。

Class<?> c = Class.class; 

可以使用,因为任何类型的类都可以是Class<Class>

Class<Class<?>> cc3 = Class.class;

不能正常工作,因为Class.class类型为Class<Class>且不属于Class<Class<?>>

类型
ArrayList<ArrayList<Integer>> lst = new ArrayList<ArrayList<Integer>>();
ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<?>>();

因为两个表达式匹配而起作用。

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList>();

不匹配。

答案 2 :(得分:2)

泛型有一些非常严重的限制。在这种情况下,您不能将类型分配给内部类型Class<Class>,因为您实际上是引用原始类型,而不是原始类型的实现。它会给你一个警告,但你没办法解决这个警告。

Class<Class<?>>本身并不是一个不可转换的类型,你只是不能直接为它分配一个类,因为它没有Class<Class<T>>类型,它的类型为{{1} }。

以另一种方式思考;试试Class<T>。要创建它,您需要创建一个带有字符串列表的List。这是有效的,因为列表可以包含列表。

一个类更像是一个原语而不是一个数据对象,所以我认为不可能创建一个Class类型为Class的类。

修改:关于List<List<String>>的额外问题是您使用ArrayList<ArrayList<?>>时遇到的不可转换类型问题的一个更明显的例子。