文章已收录到我的Github精选,欢迎Star:https://github.com/yehongzhi/learningSummary
前言
其实在开发中经常会看到泛型的使用,但是很多人对其也是一知半解,大概知道这是一个类似标签的东西。比如最常见的给集合定义泛型。
List<String> list = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
那么什么是泛型,为什么使用泛型,怎么使用泛型,接着往下看。
什么是泛型
Java泛型是J2SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter),这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。-- 百度百科
这句话读起来有点拗口,但是我们要抓住他说的关键,参数化类型
和可以用在类、接口和方法的创建中
,我们知道泛型是在什么地方使用。
为什么使用泛型
一般我在思考这种问题时,会反过来思考,假如没有泛型会怎么样?
我们以最简单的List
集合为例子,假如没有泛型:
public static void main(String[] args) {
List list = new ArrayList();
list.add("good");
list.add(100);
list.add('a');
for(int i = 0; i < list.size(); i++){
String val = (String) list.get(i);
System.out.println("val:" + val);
}
}
很显然在没有泛型的时候,List默认是Object类型,所以List里的元素可以是任意的,看起来集合里装着任意类型的参数是“挺不错”,但是任意的类型的缺点也是很明显的,就是要开发者对集合中的元素类型在预知的情况下进行操作,否则编译时不会提示错误,但是运行时很容易出现类型转换异常(ClassCastException)。
如果没有泛型,第二个小问题是,我们把一个对象放进了集合中,但是集合并不会记住这个对象的类型,再次取出时统统都会变成Object类,但是在运行时仍然为其本身的类型。
所以引入泛型就可以解决以上两个问题:
- 类型安全问题。使用泛型,则会在编译期就能发现类型转换异常的错误。
- 消除类型强转。泛型可以消除源代码中的许多强转类型的操作,这样可以使代码更加可读,并减少出错的机会。
泛型的特性
泛型只有在编译阶段有效,在运行阶段会被擦除。
下面做个试验,请看代码:
List<String> stringArrayList = new ArrayList<String>();
List<Integer> integerArrayList = new ArrayList<Integer>();
Class classStringArrayList = stringArrayList.getClass();
Class classIntegerArrayList = integerArrayList.getClass();
System.out.println(classStringArrayList ==<