【发布时间】:2016-07-23 23:51:42
【问题描述】:
这是一个来自 3rd 方库 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(); 不是?
【问题讨论】:
-
有趣!在 LHS
Integer x = getCharSequence();上强制转换将编译,但在 RHSInteger x = (Integer) getCharSequence();上强制转换编译失败 -
你使用的是什么版本的java编译器?请在问题中指定此信息。
-
@FedericoPeraltaSchaffner 不明白为什么这很重要 - 这是一个直接关于 JLS 的问题。
-
@BoristheSpider 因为java8的类型推断机制已经改变
-
@FedericoPeraltaSchaffner - 我已经用 [java-8] 标记了这个问题,但我现在在帖子中添加了编译器版本。