JAVA中的泛型,以及什么时候使用泛型

泛型:
jdk1.5出现的安全机制.

好处:

1.将运行时期的问题ClassCastException转到编译时期.
2.避免了强制类转换的麻烦

不是泛型的例子:

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
    
        ArrayList al = new ArrayList();

        al.add(new Student("st1", 15));
        al.add(new Student("st2", 18));
        al.add(new Student("st3", 16));
        
        for(Object s : al) {
            Student t = (Student) s;
            System.out.println("name:"+t.getName()+", age:"+t.getAge());
        }

    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
}

class Student extends Person{
    public Student(String name, int age) {
        super(name, age);
    }
}

class Animal {

}

这个例子中, 由于要用的Object来接收
所以在进行输出的时候就需要进行强制类型转换

for(Object s : al) {
            Student t = (Student) s; //前面是Student类型,所以就必须进行强转
            System.out.println("name:"+t.getName()+", age:"+t.getName());
        }

运行结果:
在这里插入图片描述
但是如果我们加入了其它的类

例如:

  al.add(new Animal());

这时如果编译是完全没用问题的!!!

但是由于在我们的foreach循环中,里面的Object是强制转换为学生的,

但是我们加入的是动物,想象一下,把动物变成学生是多么可怕的一件事…
这个就会使我们出现运行出错.

运行结果:
在这里插入图片描述
大致错误信息: Animal cannot be cast to Student(无法将动物投掷给学生)

这时泛型的安全机制就显示出区别来了
泛型的例子:

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
    
        ArrayList<Student> al = new ArrayList<Student>();
        al.add(new Student("st1", 15));
        al.add(new Student("st2", 18));
        al.add(new Student("st3", 16));
        
        for(Person s : al) {
            System.out.println("name:"+s.getName()+", age:"+s.getName());
        }

    }
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
}

class Student extends Person{
    public Student(String name, int age) {
        super(name, age);
    }
}

class Worker extends Person{
    public Worker(String name, int age) {
        super(name, age);
    }
}

class Animal {

}

运行结果:
在这里插入图片描述
但是我们加入其它的类呢? 例如: 动物

显示结果:
在这里插入图片描述
可以看到,我们还没有编译, 他就给我们错误提示了

所以我们说泛型的好处之一 :

			将运行时期的问题ClassCastException转到编译时期.

如果我们是要加入,学生,以及工人,还有人呢?

这时我们可以在<>里面写Person
 ArrayList<Person> al = new ArrayList<Person>();
        al.add(new Student("st1", 15));
        al.add(new Student("st2", 18));
        al.add(new Student("st3", 16));
        al.add(new Person("perhhh1", 25));
        al.add(new Person("perhhh2", 26));
        al.add(new Person("perhhh3", 28));
        al.add(new Worker("wo1", 30));
        al.add(new Worker("wo1", 30));
        al.add(new Worker("wo1", 30));
        
        for(Person s : al) {
            System.out.println("name:"+s.getName()+", age:"+s.getAge());
        }

运行结果:
在这里插入图片描
可以在代码看出,我们并没有使用强制类型转换

所以我们说泛型的另一个好处是:

		避免了强制类转换的麻烦

这就引发了我们的另一个问题泛型<>什么时候用?

1.当操作的引用的数据类型不确定的时候,就用<>.
将要操作的引用数据类型传入即可.

其实<>就是一个接收具体引用数据类型的参数范围

2.在程序中,只要用到带有<>的类或者接口,就要明确传入的具体引用数据类型

泛型技术是给编译器使用的技术,用于编译时期,确保了类型的安全

运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除.

为什么擦除?
因为为了去兼容运行的类加载器

泛型的补偿:
在运行时通过获取元素的类型进行转换动作.不用使用者在强制类型转换了

发布了87 篇原创文章 · 获赞 43 · 访问量 4020

猜你喜欢

转载自blog.csdn.net/weixin_42947972/article/details/103114185