需要不兼容的类型:找到类<t>:类<cap#1>其中T是类型变量</cap#1> </t>

时间:2014-09-18 13:37:32

标签: java generics

以下代码:

public class A<T> {

    Class<T> klass;
    T instance;

    public A(T instance) {
        this.klass = instance.getClass(); // this requires an explicit cast to Class<T> to satisfy the compiler
        this.instance = instance;
    }
}

汇编:

A.java:7: error: incompatible types
             this.klass = instance.getClass();
                                           ^
required: Class<T>
found:    Class<CAP#1>
where T is a type-variable:
  T extends Object declared in class A
where CAP#1 is a fresh type-variable:
  CAP#1 extends Object from capture of ? extends Object
1 error

为什么编译器不满足instance.getClass()将始终生成Class<T>(因为instance类型为T)并且需要显式转换?我安全只是添加显式演员:

this.klass = (Class<T>) instance.getClass();

...从而使编译器静音或是否存在运行时意外的空间?如果没有,为什么编译器不能解决这个问题呢?

1 个答案:

答案 0 :(得分:11)

  

为什么编译器不满足instance.getClass()将始终生成Class(因为实例是T类型)并且需要显式转换?

考虑一下:

A<Object> a = new A<Object>("Foo");

致电instance.getClass()不会返回Class<Object> - 它会返回Class<String>。即使每个String都是Object,它们也不是一回事。

您可以将代码更改为:

Class<? extends T> klass;

此时它逻辑安全,但它仍然需要强制转换,因为Object.getClass()只是声明返回Class<? extends |T|>(根据JLS section 4.3.2):< / p>

  

getClass的方法调用表达式的类型为Class<? extends |T|>,其中TgetClass搜索的类或接口(第15.12.1节)。

|T|部分表示T的{​​{3}},在这种情况下只是Object

当然,演员实际上并没有在执行时检查任何内容,你需要@SuppressWarnings("unchecked")来完全使编译器静音,但至少代码在这一点上会有逻辑意义。