Java 为什么使用原始类型变量会影响签名而不引用类型参数?

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位(有点不清楚)在:

查看另一个版本时,我遇到了1.8.0_112 Sun Oracle编译器的这一有趣行为(我没有与其他人一起测试过):

因此,尽管
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
。这也是你不能问是否的原因e> foo instanceof List。我想你是对的。只是我不清楚最后一部分是什么意思:“在对应于C的泛型声明中”。在我看来,如果你是对的(99.9%,如果你愿意的话)因此,仅仅说
List
的删除是
List
是不够的,但是你需要说
List
的删除是
List
在与
Alpha
So
Alpha
相对应的泛型声明中的
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