Java 为什么使用原始类型变量会影响签名而不引用类型参数?
查看另一个版本时,我遇到了1.8.0_112 Sun Oracle编译器的这一有趣行为(我没有与其他人一起测试过): 因此,尽管Java 为什么使用原始类型变量会影响签名而不引用类型参数?,java,generics,type-erasure,erasure,Java,Generics,Type Erasure,Erasure,查看另一个版本时,我遇到了1.8.0_112 Sun Oracle编译器的这一有趣行为(我没有与其他人一起测试过): 因此,尽管Alpha中的intList()返回列表类型list不依赖于类型参数T,但编译时似乎删除了 请注意,如果我们声明一个非通用接口Beta,理论上相当于引用原始Alpha,那么就没有问题了 这是预期的行为吗?有人能指出语言规范中涵盖这一点的段落吗?如果这不是一个bug的话,至少它看起来是反直觉的,没有效率的;也许是为了后面的可比性而做的?这样说的JLS位(有点不清楚)在:
Alpha
中的intList()
返回列表类型list
不依赖于类型参数T
,但编译时似乎删除了
请注意,如果我们声明一个非通用接口Beta
,理论上相当于引用原始Alpha
,那么就没有问题了
这是预期的行为吗?有人能指出语言规范中涵盖这一点的段落吗?如果这不是一个bug的话,至少它看起来是反直觉的,没有效率的;也许是为了后面的可比性而做的?这样说的JLS位(有点不清楚)在: 未从其超类或超接口继承的原始类型C的构造函数(§8.8)、实例方法(§8.4,§9.4)或非静态字段(§8.3)的类型是对应于在对应于C的泛型声明中删除其类型的原始类型 因此,由于
rawAlpha
是原始类型,rawAlpha.intList
的类型是对List intList()
的擦除。该擦除是List intList()
至于原因,我手头没有引文,但原始类型在Java中只是为了向后兼容。这意味着它们只需要像在泛型之前一样工作;你所要求的是一个比以前更好一点的代码。这不是不合理的,但这不是他们决定的。:-) 当泛型类型用作原始类型时,它会丢失所有的泛型,而不仅仅是那些依赖于你没有给出的类型的泛型。@PeterLawrey是的,似乎是这样,但问题是为什么?在Java 5.0发布时,我问过一位开发人员,在我看来,除了,它要么是用于向后兼容的原始类型,要么是泛型。没有什么不自然的,但仍然有一些理智的退路。为什么?当然,因为JLS是这么说的!甚至在11年前,人们就认识到,稀薄型可能是答案。也许他们会在Java10.mmm中。。。“是原始类型,对应于在对应于C的泛型声明中删除其类型”。。。我想说的是,文本是一种开放的解释。。。所以C在这里
Alpha
对吗?因此,文本将读为“如果它是一个声明为返回List tList()的方法,则Alpha.intList
的类型是与Alpha
对应的泛型声明中List
的擦除相对应的原始类型
这个句子完全有意义,但是List
?为什么删除T
会影响Integer
这里?@ValentinRuano因为删除List
是List
——删除意味着没有保留任何通用信息,而不仅仅是删除T
。这也是你不能问是否List
的删除是List
是不够的,但是你需要说List
的删除是List
在与Alpha
SoAlpha
相对应的泛型声明中的List
,不管这意味着什么,这同样是错误的我不太清楚。JLS语言需要一些时间来适应,但它非常客观,一点也不“受解释”。它非常准确地说明,如果使用原始类型,其所有成员也将被视为原始类型。这就是为什么你会得到结果,@ValentinRuano。
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()) {}
}
}
error: incompatible types: Object cannot be converted to Integer
for (Integer i : rawAlpha.intList()) {}
^
1 error