以下代码:
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();
...从而使编译器静音或是否存在运行时意外的空间?如果没有,为什么编译器不能解决这个问题呢?
答案 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|>
,其中T
是getClass
搜索的类或接口(第15.12.1节)。
|T|
部分表示T
的{{3}},在这种情况下只是Object
。
当然,演员实际上并没有在执行时检查任何内容,你需要@SuppressWarnings("unchecked")
来完全使编译器静音,但至少代码在这一点上会有逻辑意义。