java泛型改进_[改善Java代码]Java的泛型是类型擦除的

本文深入探讨了Java中的泛型,包括泛型如何增强类型安全性、减少类型转换,以及泛型在编译期的类型擦除机制。解释了由于类型擦除,导致的编译错误,如方法签名重复问题,并举例说明了泛型在字节码中的体现。此外,还讨论了泛型在实例化数组、使用instanceof运算符时的限制,并分析了这些限制背后的原因。
摘要由CSDN通过智能技术生成

泛型可以减少强制类型的转换,可规范集合的元素类型,还可以提高代码的安全性和可读性,正是因为有了这些优点,自从Java引入泛型之后,项目的编码规则上便多了一条,优先使用泛型.

Java泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,它与C++中的模板templates比较类似.但是有一点,Java的反省在编译期有效,在运行期被删除,也就是说所有的泛型参数类型在编译后都会被清除掉.

看如下代码:

importjava.util.List;public classFoo {//arrayMethod接受数组参数,并进行重载

public voidarrayMethod(String[] strArray){}public voidarrayMethod(Integer[] intArray){}//listMethod接收泛型List参数,并进行重载

public void listMethod(ListstrList){}public void listMethod(ListintList){}

}

编写了4个方法,arrayMethod方法接收String数组和Integer数组,这是一个典型的重载,listMethod接收元素类型为String和Integer的List变量.

但是这段代码不能通过编译,不能通过通过编译是在listMethod方法上.

提示:Erasure of method listMethod(List) is the same as another method in type Foo  &&  Erasure of method listMethod(List) is the same as another method in type Foo

是说listMethod对应的这两个方法在编译时擦除类型后的方式是listMethod(List),它与另外一个方法重复,通俗的说就是方法签名重复,这就是Java泛型擦除引起问题:在编译后所有的泛型类型都会做相应的转化.

转换规则如下:

1.List,List,List泛型擦除后的类型为List.

2.List[]擦除之后的类型是List[]

3.List extends E>,List super E>擦除之后对应类型是List

4.List擦除之后为List

Java编译后的字节码中已经没有泛型的任何信息了,也就说一个泛型类和一个普通类在经过编译后都指向了同一字节码,比如Foo类,经过编译后将只有一份Foo.class类.

不管是Foo还是Foo引用的都是同一个字节码,Java之所以这样处理有两方面原因:

1.避免JVM大换血.C++的泛型生命期延续到了运行期,而Java是在编译器擦除掉的,如果JVM也把泛型类型延续到运行期,那么JVM就需要进行大量的重构工作了.

2.版本兼容,在 编译期擦除可以更好的支持原生类型RawType,在Java1.5或1.6平台上,即使声明一个List这样的原生类型也是可以正常编译通过的,只是会产生警告信息而已.

这样就可以解释如下问题了:

(1)泛型的class对象都是相同的.

每个类都有一个class属性,泛型化不会改变class属性的返回值.例如:

1 importjava.util.ArrayList;2 importjava.util.List;3

4 public classClient {5 public static voidmain(String[] args) {6 List ls = new ArrayList();7 List li = new ArrayList();8 System.out.println(li.getClass() ==li.getClass());9 }10 }

以上代码会返回true,List和List擦除后的类型都是List,没有任何的区别.

(2)泛型数组初始化时不能声明泛型的类型

原因很简单,可以声明一个带有泛型参数的数组,但是不能初始化该数组,因为执行了类型擦除操作,List[] 与List就是一回事了,编译器拒绝如此的声明.

(3)instanceof不允许穿在泛型参数

原因 一样,泛型类型的被擦除了.

1 importjava.util.ArrayList;2 importjava.util.List;3

4 public classClient {5 public static voidmain(String[] args) {6 //List[] listArray = new List[];

7 /*

8 如上语句报错9 Multiple markers at this line10 - Variable must provide either dimension expressions or an array initializer11 - Cannot create a generic array of List12 */

13 List[] listArray2; //只声明不初始化没有问题.14 //======================================分割线============

15

16 List list = new ArrayList();17 System.out.println(list instanceof List);//没有泛型就不会报错,18 //System.out.println(list instanceof List);//有泛型就报错.

19 /*

20 Cannot perform instanceof check against parameterized type List.21 Use the form List> instead since further generic type information will be erased at runtime22 */

23

24 List list2 = new ArrayList();25 List l =list2;26 l.add(123);27 }28 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值