我得到以下编译消息:
[javac] ... error: incompatible types
[javac] exceptionClassHolder = new Holder<>( (new Exception()).getClass() );
[javac] ^
[javac] required: Holder<Class<? extends Exception>>
[javac] found: Holder<Class<CAP#1>>
[javac] where CAP#1 is a fresh type-variable:
[javac] CAP#1 extends Exception from capture of ? extends Exception
[javac] 1 error
Run Code Online (Sandbox Code Playgroud)
在我看来,根据信息所有应该是正确的.CAP#1确实扩展了Exception.那么如何理解上述信息呢?下面的SSCCE(最初没有发布,因为我希望在一般情况下理解错误消息本身):
class Holder<T> {
public T t;
public Holder(T t) {
this.t = t;
}
}
public class FooMain {
public static void main(String args[]) throws Exception {
Holder<Class<? extends Exception>> exceptionClassHolder;
exceptionClassHolder = new Holder<>( (new Exception()).getClass() );
}
}
Run Code Online (Sandbox Code Playgroud)
Pau*_*ora 24
不幸的是,现有的答案并没有解释这里发生了什么.首先,解决方案是简单地将类型参数指定为Holder:
Holder<Class<? extends Exception>> exceptionClassHolder;
exceptionClassHolder =
new Holder<Class<? extends Exception>>(new Exception().getClass());
Run Code Online (Sandbox Code Playgroud)
您的版本不起作用的原因是因为new Exception().getClass()返回a Class<? extends Exception>,其中?是通配符捕获(在编译器错误消息中称为CAP#1).由于您使用的"钻石经营者"用new Holder<>,编译器推断Class<CAP#1 extends Exception>的T,因此 Holder<Class<CAP#1 extends Exception>>是创建的对象的类型.
但是,这与您声明的类型不匹配Holder<Class<? extends Exception>>.它使用嵌套通配符,它不捕获:虽然CAP#1 extends Exception是某些特定类型的扩展Exception,但嵌套? extends Exception表示任何类型的扩展Exception.
虽然Class<CAP#1 extends Exception>是子类型Class<? extends Exception>,但Holder<Class<CAP#1 extends Exception>>不是子类型,Holder<Class<? extends Exception>>因为泛型不是协变的,因此赋值失败.
手动指定Class<? extends Exception>的T,你帮助编译器避开这个"陷阱".
在这些帖子上查看我的类似答案:
| 归档时间: |
|
| 查看次数: |
11922 次 |
| 最近记录: |