为什么使用原始类型变量会影响签名而不参考类型参数? [英] Why does using raw type variables affect signatures without reference to type-parameters?

查看:125
本文介绍了为什么使用原始类型变量会影响签名而不参考类型参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看另一个问题 I碰到1.8.0_112 Sun-Oracle编译器这个有趣的行为(我还没有和其他人一起测试过):

  import java。 util.List; 

接口Alpha< T> {
列表<整数> intList中();
}

界面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; (Integer i:charAlpha.intList()){}
for(Integer i:qmAlpha.intList()){}
for(Integer i:beta.intList ()){}
for(Integer i:rawAlpha.intList()){}
}
}

仅限编译器 在上一次for循环时失败:

  error:incompatible types:Object无法转换为Integer 
for(Integer i:rawAlpha.intList()){}
^
1错误
intList()
返回列表类型 List< / pre>

Alpha 中的整数> 不依赖于类型参数 T ,看起来< Integer> 在编译时被清除。注意,如果我们声明一个非泛型接口 Beta ,理论上它相当于引用到原始 Alpha ,没有问题。



这是预期的行为吗?有人可以指出语言规范中涉及这一点的段落吗?如果这不是一个错误,它至少看起来反直觉和非生产性;也许是为了后向可比性而完成的?。

解决方案

JLS 4.8


构造函数的类型(§8.8),实例方法(§8.4,§9.4)或非静态字段(§8.3)没有从它的超类或超接口继承的原始类型C是对应于在对应于C的通用声明中删除其类型的原始类型。


因此,由于 rawAlpha 是一个原始类型,所以 rawAlpha.intList 的类型是擦除列表<整数> intList中()。删除是列表intList()



至于为什么,我没有引用方便,但原始类型仅在Java中才具有向后兼容性。这意味着他们只需要像仿制药之前一样工作;你要求的是代码的功能已经比以前更好一些了。这不是不合理的,但这不是他们决定的。 : - )

Looking into another question I bumped into this intriguing behavior of the 1.8.0_112 Sun-Oracle compiler (I have not tested with others):

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()) {}
   }
}

The compiler only fails at the last for loop:

error: incompatible types: Object cannot be converted to Integer
      for (Integer i : rawAlpha.intList()) {}
                                       ^
1 error

So despite that intList() return list type List<Integer> in Alpha does not depend on the type parameter T, it seems that the <Integer> is erased at compilation time.

Notice that if we declare a non-generic interface Beta that would be, in theory, equivalent to making reference to the raw Alpha, there is no issues.

Is this the expected behavior? can some one point out the paragraph on the language spec that would cover this point? If this is not a bug at the very least it seem rather anti-intuitive and non-productive; perhaps is done for the sake of back-comparability?.

解决方案

The JLS bit that says this (a bit unclearly) is in 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.

So, since rawAlpha is a raw type, the type of rawAlpha.intList is the erasure of List<Integer> intList(). That erasure is List intList().

As for why, I don't have a citation handy, but raw types are only really in Java for backwards compatibility. That means they only need to work as well as they did before generics; what you're asking for is for code that works just a little bit better that it used to. It's not unreasonable, but it's not what they decided on. :-)

这篇关于为什么使用原始类型变量会影响签名而不参考类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆