我有一个以下类型的变量
Pair<String, Class<?>> test;
我试图像这样创建它:
Class<? extends Animal> animal = Tiger.class;
test = Pair.create("tiger", animal);
代码给了我&#34;不兼容的类型&#34;(创建与动物配对时)。虽然变量测试定义允许任何类型的动物和动物定义任何动物儿童类别的边界,这比原始类别更严格。那么这项任务不应该起作用吗?
答案 0 :(得分:4)
Tiger
是Animal
的子类型,但Class<Tiger>
不是 Class<Animal>
的子类型。 Class<Tiger>
和Class<Animal>
的父级为Class<?>
。
同样,Pair<String, Class<? extends Animal>>
不是Pair<String, Class<?>>
的子类型,即使Class<? extends Animal>>
是Class<?>
的子类型,它们也是不同的对象。
为了便于理解,请从集合中考虑它:如果您有Pair<String, List<?>>
,并为其分配Pair<String, List<? extends Number>>
;然后,您就可以将String
添加到列表中。 http://ideone.com/dcXnWs
在Java8中,您编写了代码作品http://ideone.com/AkK7Zv;说实话,我不确定编译器还能做什么(仍然需要深入研究新功能)。无论如何,正如您所看到的,以下示例的编译器错误非常明确:
Java8:http://ideone.com/ZRGbyr
error: incompatible types: List<Class<? extends Animal>> cannot be converted to List<Class<?>>
Java7:http://ideone.com/dcXnWs(相同代码)
error: incompatible types
答案 1 :(得分:3)
可能解释为什么它在Java 8中工作(具有改进的类型推断):
public static class Pair<A, B> {
public static <A, B> Pair<A, B> create(A a, B b) {
return new Pair<A, B>();
}
}
public static class Animal {}
public static class Tiger extends Animal {}
public static final void main(final String[] args) {
Class<? extends Animal> animal = Tiger.class;
Pair<String, Class<?>> test = Pair.create("tiger", animal);
}
根据Java Generics Subtyping Rules:
Class<? extends Animal> extends Class<?>
Pair<String, Class<? extends Animal>> extends Pair<String, Class<?>>
由于2.它在Java 7中不起作用,但Java 8使用1。:
Pair<String, Class<?>> test = Pair.create("tiger", animal);
Java 8表示参数a的类型为String
,参数b的类型为Class<?>
。因为1.是真的,它可以将第二个参数转换为Class<?>
,然后它适合变量test
的类型。
因为它可以在将单个参数传递给方法之前强制转换单个参数,所以它不必转换返回的结果(这是不可能的)。