Java中怎么擦除泛型类型

  

Java中怎么擦除泛型类型,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

<编辑类="目录">

前言

Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(类型擦除),将所有的泛型表示(尖括号中的内容)都替换为具体的类型(其对应的原生态类型),就像完全没有泛型一样。理解类型擦除对于用好泛型是很有帮助的,尤其是一些看起来“疑难杂症”的问题,弄明白了类型擦除也就迎刃而解了。

泛型的类型擦除原则是:

?消除类型参数声明,即删除& lt;祝辞及其包围的部分。

?根据类型参数的上下界推断并替换所有的类型参数为原生态类型:如果类型参数是无限制通配符或没有上下界限定则替换为对象,如果存在上下界限定则根据子类替换原则取类型参数的最左边限定类型(即父类)。

?为了保证类型安全,必要时插入强制类型转换代码。

?自动产生“桥接方法”以保证擦除类型后的代码仍然具有泛型的“多态性”。

1擦除类定义中的类型参数

1.1无限制类型擦除

当类定义中的类型参数没有任何限制时,在类型擦除中直接被替换为对象,即形如& lt; T>和& lt; ?祝辞的类型参数都被替换为对象,参见1 .

癑ava中怎么擦除泛型类型"

图1:擦除类定义中的类型参数

1.2有限制类型擦除

当类定义中的类型参数存在限制上(下)界时,在类型擦除中替换为类型参数的上界或者下界,比如形如& lt; T扩展Number>和& lt; ?Number>扩展的类型参数被替换为数字,& lt; ?超级Number>被替换为对象,参见2 .

癑ava中怎么擦除泛型类型"

图2:擦除类定义中的有限制类型参数

2擦除方法定义中的类型参数

擦除方法定义中的类型参数原则和擦除类定义中的类型参数是一样的,这里仅以擦除方法定义中的有限制类型参数为例,见3 .

癑ava中怎么擦除泛型类型"

图3:擦除泛型方法中的类型参数

3桥接方法和泛型的多态

考虑下面的代码:

public  interface  Info&肝移植;T& gt;, {   ,,,//,just  return  var: -),   ,,,T 信息(T  var),,   }   public  class  BridgeMethodTest  implements  Info&肝移植;Integer& gt;, {   ,,@Override   ,,,public  Integer 信息(Integer  var), {   ,,,,,,,return  var;   ,,,}   }

按照我们之前类型擦除的经验,在擦除类型后的代码应该是这个样子的:

public  interface  Info  {   ,,,//just  return  var   ,,,Object 信息(Object  var);   }      public  class  BridgeMethodTest  implements  Info  {   ,,@Override   ,,,public  Integer 信息(Integer  var), {   ,,,,,,,return  var;   ,,,}   }

但是,明显可以看的出,这样擦除类型后的代码在语法上是错误的:BridgeMethodTest类中虽然存在一个信息方法,但是和信息接口要求覆盖的信息方法不一致:参数类型不一致。在这种情况下,Java编译器会自动增加一个所谓的“桥接方法”(桥方法)来满足Java语法的要求,同时也保证了基于泛型的多态能够有效。我们反编译一下BridgeMethodTest。类文件可以看到Java编译器到底是如何做的:

,美元javap  BridgeMethodTest.class       得到“BridgeMethodTest.java”获Compiled       public  class  BridgeMethodTest  implements  Info< java.lang.Integer>, {      public  BridgeMethodTest ();      public  java.lang.Integer 信息(java.lang.Integer);      public  java.lang.Object 信息(java . lang . object);      }

可以看的出,Java编译器在BridgeMethodTest中自动增加了两个方法:默认构造方法和参数为对象的信息方法,参数为对象的信息方法就是“桥接方法”。如何理解“桥接”二字呢?我们进一步反编译BridgeMethodTest看一下:

//, Decompiled  by  Jad  v1.5.8e只Copyright  2001年,Pavel  Kouznetsov只,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,//,Jad  home 页面:http://www.geocities.com/kpdus/jad.html   时间选择://,Decompiler  packimports (3),//,Source  File 名称:,,BridgeMethodTest.java   ,   ,   public  class  BridgeMethodTest   ,,,implements 信息   {   ,   ,,,public  BridgeMethodTest ()   ,,,{,,   ,,,},,,   ,   ,,,public  Integer 信息(Integer 整数)   ,,,{,,   ,,,,,,,return 整数;   ,,,},,,   ,   ,,,public  volatile  Object 信息(Object  obj)   ,,,{,,   ,,,,,,,return 信息((整数)obj);   ,,,},,,   }

Java中怎么擦除泛型类型