为什么用泛型?
在定义类时,不知道类是什么类型,而我们又不能定义多个类型,所以用一个模糊的类型——泛型来修饰类。
给了代码更高的使用率,不会因为不同类型(ClassCaseException)而导致代码复用率低。
代码理解:
理解下述代码为何出错
import java.util.*; //泛型需要引入uitl包
public class Test1 {
public static void main(String[] args)
{
ArrayList a1=new ArrayList(); //创建一个ArrayList集合类,没有规定泛型,此时类型为Object
Dog dog1=new Dog(); //创建一只狗dog1
a1.add(dog1); //把dog1加入到集合中,这时集合的第一个是狗类型
Cat temp=(Cat)a1.get(0); //取出集合第一个元素,并向下强转为猫类型
}
}
class Cat //定义猫类
{
private String color;
private int age;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Dog //定义狗类
{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
为什么错呢?各位程序猿们看懂了吗?
就是因为我在取的时候,第一个元素是狗类却强转为猫类,导致强转异常,运行出错。但是在编译时不会提示,因为ArrayList没有规定泛型,默认为Object,任何对象都可以放入这个集合中,编译器认为它是从Object类转为猫类的。
这时候就可以引出泛型了!
我把第五行的集合类,这样写:
ArrayList <Dog>a1=new ArrayList<>();
中间加个狗类,这个集合只会与狗有关,不能加入猫,就可以防止上述错误的产生。
最主要的是泛型可以提高代码复用率:
public class Test1 {
public static void main(String[] args)
{
Gen <String> gen1=new Gen<>("aaa"); //把泛型定义为String具体类型
gen1.showTypeName();
Gen <Integer> gen2=new Gen<>(111); //把泛型定义为Integer具体类型
gen2.showTypeName();
Gen <Double> gen3=new Gen<>(111.1); //把泛型定义为Double具体类型
gen3.showTypeName();
}
}
class Gen<T> //定义Gen类,指明是泛型类
{
private T o; //泛型的变量
public Gen(T o)
{
this.o=o;
}
public void showTypeName() //可以映射o的类型名的方法
{
System.out.println("类型是:"+o.getClass().getName());
}
}
从上述代码看出,我把Gen定义为一个泛型,用T代表,我不知道它到底是什么类型。
在主函数中,我给泛型一个具体的类型,就可以使用这个具体类型的操作,这样的话,一个泛型类,可以做出各种不同类型的操作,是不是提高的代码的复用率?
输出结果:
类型是:java.lang.String
类型是:java.lang.Integer
类型是:java.lang.Double
泛型的好处:
类型安全:付给泛型具体类型后,不会因为强转而出错,编译器会告诉你,只能有这个类型的对象。
层次清晰:很清晰,使用时赋个类型,是哪个类型的就是哪个类型的。
性能较高:可以使用各种类型,提高复用率。
向后兼容:可以用于泛型类,泛型接口,泛型方法等等。