调查另一个question我碰到了1.8.0_112 Sun-Oracle编译器的这种有趣的行为(我没有和其他人一起测试过):
import java.util.List;
interface Alpha<T> {
List<Integer> intList();
}
interface Beta {
List<Integer> intList();
}
class Main {
public static void main(String[] args) {
Alpha rawAlpha = null;
Alpha<Character> charAlpha = null;
Alpha<?> qmAlpha = null;
Beta beta = null;
for (Integer i : charAlpha.intList()) {}
for (Integer i : qmAlpha.intList()) {}
for (Integer i : beta.intList()) {}
for (Integer i : rawAlpha.intList()) {}
}
}
编译器 only 在最后一个for循环失败:
error: incompatible types: Object cannot be converted to Integer
for (Integer i : rawAlpha.intList()) {}
^
1 error
尽管intList()
中的List<Integer>
返回列表类型Alpha
不依赖于类型参数T
,但似乎<Integer>
已被删除编译时间。
请注意,如果我们声明一个非泛型接口Beta
,理论上相当于引用原始Alpha
,那么就没有问题。
这是预期的行为吗?是否有人能指出涵盖这一点的语言规范段落?如果这不是一个错误,它至少看起来反直觉和非生产性;也许是为了背部可比性?
答案 0 :(得分:12)
这个(有点不清楚)的JLS位在JLS 4.8:
未从其超类或超接口继承的原始类型C的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)的类型是原始类型对应于在与C相对应的通用声明中擦除其类型。
因此,由于rawAlpha
是原始类型,因此rawAlpha.intList
的类型是List<Integer> intList()
的删除。该删除是List intList()
。
至于为什么,我没有引用方便,但原始类型只是用于向后兼容的Java。这意味着他们只需要像仿制药一样工作;您要求的是代码,它比以前更好一些。这不是没有道理的,但并不是他们决定的。 : - )