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



我有一个类型的变量

Pair<String, Class<?>> test;

我正试图这样创建它:

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

代码给了我"不兼容类型"(在创建与动物配对时)。尽管可变测试定义允许任何类型的类别,动物定义任何子类别动物的边界,这比原始定义更严格。那么这个作业不应该起作用吗?

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<?>>,并且你给它分配了一个CCD13;然后您就可以将CCD_ 14添加到列表中。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

它在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泛型子类型规则:

  1. 确实:Class<? extends Animal> extends Class<?>
  2. 错误的是:Pair<String, Class<? extends Animal>> extends Pair<String, Class<?>>

因为2。它在Java7中不起作用,但Java8使用1.:

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

Java 8推断出参数a的类型为String,参数b的类型为Class<?>。因为1。如果为true,则可以将第二个参数强制转换为Class<?>,然后CCD_21适合变量test的类型。

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

最新更新