学科分类
目录
Java基础

泛型

通过前面的学习,了解到集合中可以存储任意类型的对象元素,但是当把一个对象存入集合后,集合会“忘记”这个对象的类型,将该对象从集合中取出时,这个对象的编译类型就统一变成了Object类型。换句话说,在程序中无法确定一个集合中的元素到底是什么类型,那么在取出元素时,如果进行强制类型转换就很容易出错。接下来通过一个案例来演示这种情况,如文件1所示。

文件1 Example23.java

 1    import java.util.ArrayList;
 2    public class Example23 {
 3        public static void main(String[] args) {
 4            ArrayList list = new ArrayList();     
 5            list.add("String");                     // 添加字符串对象
 6            list.add("Collection");                
 7            list.add(1);                        // 添加Integer对象
 8            for (Object obj : list) {            
 9                String str = (String) obj;        // 强制转换成String类型
 10                System.out.println(str);
 11            }
 12        }
 13    }

运行结果如图1所示。

图1 运行结果

文件1中,向List集合存入3个元素,分别是两个字符串和一个整数。在取出这些元素时,都将它们强转为String类型,由于Integer对象无法转换为String类型,因此在程序运行时会出现如图6-35所示“ClassCastException(类型转换异常)”的错误。为了解决这个问题,在Java中引入了“参数化类型(parameterized type)”这个概念,即泛型。泛型可以限定操作的数据类型,在定义集合类时,可以使用“<参数化类型>”的方式指定该集合中存储的数据类型,具体格式如下:

ArrayList<参数化类型> list = new ArrayList<参数化类型>();

接下类对文件1中的第4行代码进行进行修改,使用泛型来限定ArrayList集合中只能存储String类型的数据,如下所示:

ArrayList<String> list = new ArrayList<String>();

代码修改之后,会发现程序在编译时期就会出现错误提示,如图2所示。

图2 编译错误

在图2中,程序编译报错的原因是修改后的代码限定了集合元素的数据类型,ArrayList<String>这样的集合只能存储String类型的元素,程序在编译时,编译器检查出Integer类型的元素与List集合的规定的类型不匹配,编译不通过,这样就可以在编译时期解决错误,避免程序在运行时期发生错误。

接下来使用泛型再次对文件1进行改写,如文件2所示。

文件2 Example24.java

 1    import java.util.ArrayList;
 2    public class Example24 {
 3        public static void main(String[] args) {
 4             // 创建ArrayList集合,使用泛型
 5            ArrayList<String> list = new ArrayList<String>();
 6            list.add("String");             // 添加字符串对象
 7            list.add("Collection");
 8            for (String str : list) {     // 遍历集合,可以直接指定元素类型
 9                System.out.println(str); 
 10            }
 11        }
 12    }

运行结果如图3所示。

图3 运行结果

文件2中,使用泛型规定了ArrayList集合只能存入String类型元素,之后向集合中存入了两个String类型元素,并对这个集合进行遍历,从图3可以看出,该文件可以正常运行。需要注意的是,在使用泛型后每次遍历集合元素时,可以指定元素类型为String,而不是Object,这样就避免了在程序中进行强制类型转换。

点击此处
隐藏目录