学习笔记,仅供参考
收集的泛型Blog:泛型
泛型
泛型的概述
- 泛型概述
- 通常而言我们只会使用容器来存储一种类型的对象。泛型的主要目的之一就是用来指定容器要持有什么类型的,因此与其使用Object,我们更喜欢暂时不指定类型,而是稍后再决定具体使用什么类型。要达到这个目的,需要使用类型参数,用尖括号括住,放在类名后面。然后在使用这个类的时候,再用实际的类型替换此类型参数。
- 泛型好处
- 提高安全性(将运行期的错误转换到编译期)
- 省去强转的麻烦
- 泛型基本使用
<>
中放的必须是引用数据类型
举个例子
我在ArrayList中放多种数据类型,代码如下:
package com.guiyang.restudy3;
import java.util.ArrayList;
import java.util.Iterator;
import com.guiyang.bean.Person;
public class D1Genric {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(110);
list.add(true);
list.add(new Person("张三", 23));
list.add(new Person("李四", 24));
Iterator it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
输出:
110
true
Person [name=张三, age=23]
Person [name=李四, age=24]
现在,我想调用集合中元素的getName方法。由于,Person的父类Object类中不存在getName方法,所以我们需要对元素进行强制向下转型:
package com.guiyang.restudy3;
import java.util.ArrayList;
import java.util.Iterator;
import com.guiyang.bean.Person;
public class D1Genric {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(110);
list.add(true);
list.add(new Person("张三", 23));
list.add(new Person("李四", 24));
Iterator it = list.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.getName() + "..." + p.getAge());
}
}
}
报错信息:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to com.guiyang.bean.Person
at com.guiyang.restudy3.D1Genric.main(D1Genric.java:19)
ClassCastException异常,是JVM在检测到两个类型间转换不兼容时引发的运行时异常。
在上面的代码中,我们引发了ClassCastException异常,这是由于我们试图对Integer强制转换为Person类时发生的异常,这个异常在编译时没有显露出来。
如果我想让这个错误在编译阶段就暴露,我就需要用到泛型,规定只有Person类及其子类可以进入ArrayList:
ArrayList<Person> list = new ArrayList<Person>();
当我们给ArrayList加上泛型之后,Java就会提示我们出现了编译时错误:
我们把这俩行代码删除后,再运行:
package com.guiyang.restudy3;
import java.util.ArrayList;
import java.util.Iterator;
import com.guiyang.bean.Person;
public class D1Genric {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<Person>();
list.add(new Person("张三", 23));
list.add(new Person("李四", 24));
Iterator<Person> it = list.iterator();
while(it.hasNext()) {
Person p = it.next();
//由于我们利用泛型获取到的都是Person对象,所以就可以不用向下强转了
System.out.println(p.getName() + "..." + p.getAge());
}
}
}
输出:
张三...23
李四...24
- 注意事项
前后泛型必须一致,下面,我们分别列出了正确的和错误的写法:
//正确的(前后一致)
ArrayList<Person> list = new ArrayList<Person>();
//错误的(前后不一致)
ArrayList<Person> list = new ArrayList<Object>();
当我们在前面定义过泛型之后,后面的泛型可以不定义,若定义了,则前后必须一致:
//正确的(前定义,后不定义)
ArrayList<Person> list = new ArrayList<>();
最后,注意泛型最好不要定义为Object,不会报错,但是没意义:
//没意义
ArrayList<Object> list = new ArrayList<>();