为什么要引入泛型?
集合中可以存储任意类型的对象元素,
但是当把一个对象存入集合后,集合会“忘记”这个对象的类型,
将该对象从集合中取出时,这个对象的编译类型就统一变成了Object类型。
换句话说,在程序中无法确定一个集合中的元素到底是什么类型,
那么在取出元素时,如果进行强制类型转换就很容易出错。
泛型是什么?
定义:泛型可以限定操作的数据类型,在定义集合类时,可以使用“<参数化类型>”的方式指定该集合中存储的数据类型。
语法:以ArrayList集合为例
使用:以ArrayList集合为例
在强制转换时一定要严格注意的一点:
int类型的包装类不能被强制转换为String类型
但是可以调用Integer的toString方法,使Integer转换为String类型
代码演示:
package jiHe;
import java.util.*;
public class FanXing_1 {
public static void main(String[] args) {
List list = new ArrayList();
list.add("String");
list.add("pekapeka");
list.add(33);
System.out.println(list);
}
}
上面的代码正常运行,那么继续向下看:
package jiHe;
import java.util.*;
public class FanXing_1 {
public static void main(String[] args) {
List list = new ArrayList();
list.add("String");
list.add("pekapeka");
list.add(33);
for(Object e : list)
{
String str = (String ) e ;//强制转换
System.out.println(str);
}
}
}
在上面的代码中可以清楚的看到报错了,但是字符串可以正常的输出
原因就是,String可以进行强转,但是Integer不能进行强转为String类型
那怎么去解决这个问题呢?
那么就要用到我们所要讲的泛型
上面的代码中向list集合存人3个元素,分别是两个字符串和一个整数。
在取出这些元素时,都将它们强转为String类型,由于Integer 对象无法转换为String类型,
因此在程序运行时会出现如图所示“ClassCastException(类型转换异常)”的错误。
为了解决这个问题,在Java中引人了“参数化类型( parameterized type)”这个概念,即泛型。
泛型可以限定操作的数据类型,在定义集合类时,可以使用“<参数化类型>”的方式指定该集合中存储的数据类型,
具体格式如下:
ArrayList<参数化类型> list =new ArrayList<参数化类型> ();
接下来对上述代码进行修改,使用泛型来限定ArrayList集合中只能存储String类型的数据
当引入了泛型之后,在list集合添加元素的时候就直接会报错,方便与元素的添加遍历等
代码修改之后,会发现程序在编译时期就会出现错误提示。
在上面代码中,程序编译报错的原因是修改后的代码限定了集合元素的数据类型,
ArrayList<String>这样的集合只能存储String类型的元素。
程序在编译时,编译器检查出Integer类型的元素与List集合的规定的类型不匹配,
编译不通过,这样就可以在编译时期解决错误,避免程序在运行时期发生错误。
再次对上的报错进行修改
package jiHe;
import java.util.*;
public class FanXing_2 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("String");
list.add("pekapeka");
for(Object e : list)
{
String str = (String ) e ;
System.out.println(str);
}
}
}
使用泛型规定了ArrayList集合只能存入Sring类型元素,
之后向集合中存入了两个String类型元素,并对这个集合进行遍历,
可以看出,该例程可以正常运行
。需要注意的是,在使用泛型后每次遍历集合元素时,
可以指定元素类型为String,而不是Object,
这样就避免了在程序中进行强制类型转换。