目录
1、为什么引入泛型?
Java是一种强类型语言,也就是每一种数据类型都有其内存模型进行约束,不同的数据类型的内存模型是一样的,因此对不同数据类型的操作行为也是不一样的。
但是Java存在继承和多态特性,子类往往都会拥有父类部分的内存模型,因此父类引用往往可以直接地引用其子类对象,这就是自然地向上转型。所以Object类可以引用任意类型的对象而不报错。
但是想要使用子类数据类型特有的内存模型部分,就需要手动地向下转型,而就是向下转型这部分最容易报错。
因为Object可以随意引用各种数据类型,但是如果一个容器里面存放了很多被Object引用的数据类型,如何不报错的进行向下转型呢?除非提前知道容器里面每一个元素的数据类型。
public void test() { ArrayList list = new ArrayList(); // 使用Object引用各种数据类型而不会报错 list.add("aaa");//引用字符串 list.add("bbb");//引用字符串 list.add("ccc");//引用字符串 list.add(111);//引用Integer for (int i = 0; i < list.size(); i++) { /* 如果某个接盘侠不知道list里面还有Integer的话,向下强转为String直接报错, 且里面有几万个元素,排除问题也麻烦*/ System.out.println((String)list.get(i)); } }
但是这种方法对开发效率来说非常低下。
最好的方式如下:
一个容器里面都存相同的数据类型,然后使用Object进行引用,向下转型时就不用关心数据类型不同带来的麻烦。
或者对数据进行二次封装时,就指定这个类只能处理某种类型的数据类型,这样也不用担心类型转换报错了。
public void test() { ArrayList<String> list = new ArrayList<>();//提前声明这个容器只能放String类型 list.add("aaa"); /* 按照要求储存一个字符串"aaa",但是这个字符串还得被Object进行引用,只有用到 这个字符串的时候才进行向下强转为字符串,然后就可以使用字符串这种数据类型 的方法和属性,比如大小写转换*/ list.add("bbb"); list.add("ccc"); list.add(111); // 在编译阶段,编译器会报错,提示你不要放其他数据类型进去, //要不然后面的方法无法操作你这种数据类型,毕竟整数111可没有大小写转换 for (int i = 0; i < list.size(); i++) { // 直接强转,再也不用担心Cast问题了 System.out.println((String)list.get(i)); } }
总结: