- 1,什么是泛型?为什么要使用泛型?
1),保存元素时:泛型解决了元素存储的安全性问题
2),获取元素时:泛型解决了类型强壮的恶心编码味道
详细点来说,java的集合有一个致命的弱点,把一个对象丢在集合里面,集合就会忘记这个对象的数据类型。当我们取出该对象的时候,这个对象的编译类型就变成了Object类型的了,注意,这个时候运行时的类型没有变的。JDK设计成这个样子是有他们的原因的,因为他们要求集合有更好的通用性,所以他们把集合设计成了可以保存任何类型的对象。当时这样子很容易出现2种恶心的地方:
1),添加一个对象到集合中,数据不安全了。比如我想放一个A对象,结果我不小心放入了一个B对象,这样子也是可以的。
2),从这个集合中抓这个对象出来,编译时类型由原来的类型统一变成了Object类型,如果我们使用也只能向下强壮,不仅增加了编程的复杂度,而且很容易引发ClassCastException异常。讲到这里顺便要T一下,我们要养成向下强壮时做类型检查的习惯,具体见下面的代码:
public class Test { public void test() { Object test = new Object(); //一旦做向下强转,就应该先做类型检查,保证代码健壮性 if (test instanceof Test) { Test test1 = (Test) test; } } }
OK,以下是代码演示,如果不使用泛型,让我们试试我们的编码是多么恶心。
public class Test { public static void main(String[] args) { //首先这里数据不安全,我本来是要想放字符串进集合的,结果不小心放了数字了,丫的编译不会有问题的 List list = Lists.newArrayList(); list.add("1"); list.add(2); for (Object object : list) { //不加入泛型,下面的代码的类型默认都是object的,所以在使用的时候,需要强转 String str = (String) object; //java.lang.Integer incompatible with java.lang.String System.out.println(str); } } }上面的代码编译不存在问题,但是在实际运行时会报类型转换错误,java.lang.Integer incompatible with java.lang.String。
OK,那现在我们来使用泛型,来看下我们的编码。
public class Test { public static void main(String[] args) { List<String> list = Lists.newArrayList(); list.add("1"); //你要是这里放入list中的对象的类型不对的话,编译就不通过 list.add(2); //在迭代循环list的时候,也不需要自己来每次强转类型了 for (String str : list) { System.out.println(str); } } }
现在来总结下泛型的作用:
1),类型安全。使编译器对泛型定义的类型做判断限制,如保证TreeSet里的元素类型必须一致。
2),消除强制类型的转换,如使用Comparable比较时每次都需要类型强转。
OK,现在关于为什么要使用泛型已经解释的很明白了,下一篇我会详细的介绍下泛型的相关基本语法。