注意:完全出于好奇而不是任何实际用例。
我想知道是否有办法用有效的类型参数声明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
如果Class
和Class<?>
可以互换,为什么Class<Class>
和Class<Class<?>>
不可以?
编辑:这个问题可以推广到嵌套原始类型参数的问题。例如:
ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList>(); //same compile error
EDIT2:我应该稍微改一下这个问题:我知道
Class<?> c = Class.class;
有效,但我想知道为什么Class<Class>
与Class<Class<?>>
不一样
答案 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<?>>
时遇到的不可转换类型问题的一个更明显的例子。