【发布时间】:2020-11-06 08:20:55
【问题描述】:
我最近被以下 Java 代码弄得措手不及:
interface Common {}
interface A extends Common {}
static class B implements Common {}
static class Impl {
private A a;
public <T extends A> T translate() {
return (T) a;
}
}
static class Usage {
public void use() {
Impl impl = new Impl();
B b = impl.translate(); // Why does this compile?
}
}
考虑到B 没有扩展A,我本来预计Impl.translate 上的类型约束不允许将结果存储在B 类型中以被编译器接受。
代码在运行时抛出UncheckedCastException,而不是编译器错误。
这只发生在方法返回类型T时;如果是方法参数:
public <T extends A> void translate(T t) {}
那么B 的实例不允许作为translate 的参数,正如预期的那样。
这里发生了什么?为什么 Java 的类型系统允许这样做?
【问题讨论】:
-
我也很好奇你是如何编译
static class B implements Common {}的。static如果不在其他类的内部,则不能创建类。static class Impl和static class Usage相同 -
the Error Prone checker for this pattern的描述可能有助于理解。请注意,它可以编译,但带有未经检查的强制转换警告。
-
我认为这就是实际发生的情况:stackoverflow.com/questions/38092697/…
-
„...请您不接受我的回答,以便我删除它吗?...“@AndyTurner — 我尊重一个不卖东西的人-为几十万的互联网点数出他的诚信:)