编程语言
首页 > 编程语言> > java – 为什么使用原始类型变量会影响签名而不引用类型参数?

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

作者:互联网

参见英文答案 > Why does javac complain about generics unrelated to the class’ type arguments?                                     1个
看看另一个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()) {}
   }
}

编译器仅在最后一个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,那么就没有问题.

这是预期的行为吗?是否有人能指出涵盖这一点的语言规范段落?如果这不是一个错误,它至少看起来反直觉和非生产性;或许是为了背部可比性而做的?

解决方法:

说这个(有点不清楚)的JLS位是在JLS 4.8

The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

因此,由于rawAlpha是原始类型,因此rawAlpha.intList的类型是List< Integer>的擦除. intList中().该擦除是List intList().

至于为什么,我没有引用方便,但原始类型只是用于向后兼容的Java.这意味着他们只需要像仿制药一样工作;您要求的是代码,它比以前更好一些.这不是没有道理的,但并不是他们决定的.

标签:java,generics,erasure,type-erasure
来源: https://codeday.me/bug/20191001/1838881.html