前言
泛型是Java中一个比较重要的特性,是于JDK5引入新特性,其主要目的是为了提供编译时的类型安全检测机制和简化代码。本文主要探讨一下泛型的使用。
假如说没有泛型
假如说没有泛型,可以举一个例子:
ArrayList list = new ArrayList();
list.add("Hello");
list.add(123);
list.add(true);
list.add(3.14);
System.out.println(list);
假如说ArrayList没有泛型的限制,那么任意类型的数据都可以存放到ArrayList集合中,并且没有任何错误——看似还不赖,这样只需要创造一个集合就可以存放任何数据了,可是真的是这样吗?显然不是——假如说我们想要从集合中取出元素来使用,调用get方法,这时就会发现其弊端:
很显然,这段代码报错了,但是索引0处是有元素的,不存在索引越界问题;那应该就是类型不匹配的问题了,让我们细看一下报错的原因:
什么情况?按照上文的代码索引0处应该存储的元素是"hello",这应该是一个String类型的元素啊,为什么变成了Object类型的?这就要提到一个Java编译的特性了——类型擦除 :在Java中,泛型是在编译时处理的,编译器会在编译过程中移除所有的泛型类型信息,这个过程称为类型擦除。类型擦除的结果是,所有的泛型类型参数都会被替换为它们的上界(如果没有指定上界,则替换为Object),但是我们没有泛型,所以说就自动提升到Object了,所以说取出来的元素的类型是Object。
集合中存放多种类型数据的弊端
上文提到了在没有泛型的情况下,取出来的元素都是Object类型的,但是Object作为顶级父类,我们可以对它进行强制类型转换,转换成我们想要的数据类型——的确可以这么使用,但是假如说集合中存放了多种类型的数据,我们不得不根据不同数据的类型,写很多强制转换的代码,这未免也太不方便了;并且就算不嫌麻烦,愿意写很多强制类型转换的代码,但是还有一个致命的问题:
这个代码,我们把索引1的元素(int 123)强转为String的类型,本地IDE是没有报错的!假如我们不小心强制类型转换的时候写了错误的类型,编译器不会报错,只会把错误,留在运行时。
泛型的好处
所以说以上可以总结出两个不用泛型的弊端——安全性不足;使用集合等太过麻烦。所以说我们要使用泛型,它是为了为了提供编译时的类型安全检测机制和简化代码而产生的。它有两个主要的好处:1.把运行时期发生的问题提前到了编译的时期;2.避免了强制类型转换,所以说在使用集合等的时候,除非是特殊情况,不然就一定要使用泛型。