泛型的概念: 泛型就是把要操作的数据类型指定为一个参数,即参数化类型。
但看这句话是不是还有点懵?没关系,先来看个例子。
例1:
private void generic(){
List list = new ArrayList();
list.add("111");
list.add("222");
list.add(333);
for(int i = 0; i< list.size(); i++){
String number = (String) list.get(i);
System.out.println("number = "+number);
}
}
在 例1 的 generic() 方法中定义了一个List类型的集合,然后在集合中添加了两个String类型和一个int类型的数据,这是被允许的,因为集合元素默认类型为Object类型,而Object类有是所有类的父类。
但有时候,我们可能会忘记往List集合中添加过几种类型的数据,然后在for循环中取出我们记得的其中一种并强制转换为该数据类型(这里是String类型)来使用,这时Java并没有提示语法错误,但强制类型转换是不安全的,在程序运行期间可能发生“ClassCastException”异常。
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
那么你可能会想“不强制类型转换不就行了”?答案是,也不行!因为集合元素并不会随着传入的数据类型而改变,必须要将Object类型强制转换为String类型才能使用,否则Java就会提示语法错误:
error: incompatible types: Object cannot be converted to String
那么取出集合中的数据时,不强制转类型转换,语法会错误,而强制转类型转换,程序可能会出现异常。所以,遇到这类问题就需要提前对List集合指定添加数据类型,即指定泛型。如以下例子,
例2:
private void generic(){
//指定泛型为String类型
List<String> list = new ArrayList<String>();
list.add("111");
list.add("222");
//添加其他类型的数据会报错
//list.add(333);
for(int i = 0; i< list.size(); i++){
//不用强制类型转换
String number = list.get(i);
System.out.println("number = "+number);
}
}
例2中指定了List集合的泛型为String类型,即“把要操作的数据类型指定为一个参数”后,集合中就只能添加指定类型的参数,也就明确了参数类型,就不用强制类型转换,所以程序也就不会出现上面提到的语法错误和运行异常的问题。