以下代码:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
汇编:
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
Run Code Online (Sandbox Code Playgroud)
为什么编译器不满足instance.getClass()将始终生成Class<T>(因为instance是类型T)并且需要显式转换?我安全只是添加显式转换:
this.klass = (Class<T>) instance.getClass();
Run Code Online (Sandbox Code Playgroud)
...从而使编译器静音或者是否存在运行时意外的空间?如果没有,为什么编译器不能解决这个问题呢?
Jon*_*eet 11
为什么编译器不满足instance.getClass()将始终生成Class(因为实例是T类型)并且需要显式转换?
考虑一下:
A<Object> a = new A<Object>("Foo");
Run Code Online (Sandbox Code Playgroud)
呼叫instance.getClass()不会返回Class<Object>- 它将返回一个Class<String>.它们不是一回事,即使每一个String都是一个Object.
您可以将代码更改为:
Class<? extends T> klass;
Run Code Online (Sandbox Code Playgroud)
此时它在逻辑上是安全的,但它仍然需要强制转换,因为Object.getClass()它只是声明返回Class<? extends |T|>(根据JLS第4.3.2节):
该类型的方法调用表达式的
getClass是Class<? extends |T|>其中T是的类或接口搜寻(§15.12.1)getClass.
的|T|部分是指类型擦除的T,在这种情况下,只是将是Object.
当然,演员实际上并没有在执行时检查任何东西,你需要@SuppressWarnings("unchecked")完全静音编译器,但至少代码在这一点上具有逻辑意义.
| 归档时间: |
|
| 查看次数: |
4898 次 |
| 最近记录: |