4

注意:纯粹出于好奇,而不是针对任何实际用例。

我想知道是否有办法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<?>>

4

3 回答 3

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!
于 2011-05-20T00:02:43.783 回答
2

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

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

Class<?> c = Class.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>();

不匹配。

于 2011-05-20T00:04:22.400 回答
2

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

Class<Class<?>>本身不是不可转换的类型,您不能直接为它分配一个类,因为它没有 type Class<Class<T>>,它有 type Class<T>

换个方式想一想;试试List<List<String>>。要创建它,您需要创建一个包含字符串列表的列表。这是有效的,因为列表可以包含列表。

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

编辑:您的额外问题ArrayList<ArrayList<?>>是您遇到的不可转换类型问题的一个更明显的例子Class<Class<?>>

于 2011-05-20T00:09:00.917 回答