通用类型赋值表示不兼容的类型,用于更严格的赋值

时间:2015-02-16 13:49:06

标签: java generics

我有一个以下类型的变量

Pair<String, Class<?>> test;

我试图像这样创建它:

Class<? extends Animal> animal = Tiger.class;
test = Pair.create("tiger", animal);

代码给了我&#34;不兼容的类型&#34;(创建与动物配对时)。虽然变量测试定义允许任何类型的动物和动物定义任何动物儿童类别的边界,这比原始类别更严格。那么这项任务不应该起作用吗?

2 个答案:

答案 0 :(得分:4)

TigerAnimal的子类型,但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;说实话,我不确定编译器还能做什么(仍然需要深入研究新功能)。无论如何,正如您所看到的,以下示例的编译器错误非常明确:

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

  1. 确实如此:Class<? extends Animal> extends Class<?>
  2. 错误地说:Pair<String, Class<? extends Animal>> extends Pair<String, Class<?>>
  3. 由于2.它在Java 7中不起作用,但Java 8使用1。:

    Pair<String, Class<?>> test = Pair.create("tiger", animal);
    

    Java 8表示参数a的类型为String,参数b的类型为Class<?>。因为1.是真的,它可以将第二个参数转换为Class<?>,然后它适合变量test的类型。

    因为它可以在将单个参数传递给方法之前强制转换单个参数,所以它不必转换返回的结果(这是不可能的)。

相关问题