泛型的擦除——擦除的神秘之处

    在我深入看泛型的时候发现的一个疑惑,

    当你开始更深入的钻研泛型的时,会发现大量的东西初看起来是没有意义的。例如,尽管可以申明ArrayList.class,但是不能申明ArrayList<Integer>.class。请考虑下面情况

   

 public class ErasedTypeEquivalence{
        public static void main(String[] args){
           Class c1 = new ArrayList<Integer>();
           Class c2 = new ArrayLsit<String>();
          System.out.println(c1 == c2);
       }
  }
//输出结果
 true

     ArrayList<Integer>和ArrayList<String>很容易被认为是不同类型。不同类型在行为方面肯定不同,例如,如果尝试将一个Integer放入ArrayList<String>,得到的行为将失败,与把一个Integer放入ArrayList<Integer>将成功得到的行为完全不同。但是上面的程序将任务他们是相同的类型。

下面这段代码将进一步的解释:

class Frob{}
class Fnorkle{}
class Quark<Q>{}
class Particle<POSTITION,MOMENTUM>{}


public class ErasedTypeEquivalence{
     public static void main(String[] args){
        List<Frob> list = new ArrayList<Frob>();
        Map<Frob,Fnorkle> map = new HashMap<Frob,Fnorkle>();
        Quark<Fnorkle> quark = new Quark<Fnorkle>();
        Particle<Long,Double> particle = new Particle<Long,Double>();
        System.out.println(Arrays.toString(list.getClass().getTypeParameters()));
        System.out.println(Arrays.toString(map.getClass().getTypeParameters()));
        System.out.println(Arrays.toString(quark.getClass().getTypeParameters()));
        System.out.println(Arrays.toString(particle.getClass().getTypeParameters()));
     }
 }
/*Output*/
[E]
[K,V]
[Q]
[POSITION,MOMENTUM]

      根据JDK文档描述,Class.getTypeParameters()将“返回一个TypeVariable对象数组,表示有泛型申明所申明的类型参数.....”,这好像是暗示你可能发现参数类型的信息,但是,正如你从输出中所看到的的,你能够发现的只是用作参数占位符的标识,这并非有用的信息。

      在泛型代码内部,无法获得任何有关泛型参数类型的信息。

      因此,你可以只掉诸如类型参数标识符和泛型类型边界这类的信息——你却无法知道用来创建某个特定实例的实际的类型参数。

     Java泛型是使用擦除来实现的,这以为着当你在使用泛型的时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。因此List<String>与List<Integer>在运行时事实上是相同类型。这两种形式都被擦除成它们的“原生”类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值