这是来自第三方库API的真实示例,但已简化。
与Oracle JDK 8u72一起编译
考虑以下两种方法:
<X extends CharSequence> X getCharSequence() {
return (X) "hello";
}
<X extends String> X getString() {
return (X) "hello";
}
两者都报告“未经检查的演员表”警告-我明白原因。让我感到困惑的是为什么我可以打电话
Integer x = getCharSequence();
它可以编译吗?编译器应该知道Integer
没有实现CharSequence
。致电
Integer y = getString();
给出错误(按预期)
incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String
有人可以解释为什么将这种行为视为有效吗?有什么用?
客户端不知道此调用是不安全的-客户端的代码在编译时不会发出警告。为何编译器不会对此发出警告/发出错误?
此外,它与此示例有何不同:
<X extends CharSequence> void doCharSequence(List<X> l) {
}
List<CharSequence> chsL = new ArrayList<>();
doCharSequence(chsL); // compiles
List<Integer> intL = new ArrayList<>();
doCharSequence(intL); // error
尝试通过List<Integer>
给出了错误,如预期的那样:
method doCharSequence in class generic.GenericTest cannot be applied to given types; required: java.util.List<X> found: java.util.List<java.lang.Integer> reason: inference variable X has incompatible bounds equality constraints: java.lang.Integer upper bounds: java.lang.CharSequence
如果报告为错误,为什么Integer x = getCharSequence();
不这样做?
Integer x = getCharSequence();
会编译,但RHS上的投射会编译Integer x = (Integer) getCharSequence();
失败