第三次学JAVA再学不好就吃翔(part82)--泛型

学习笔记,仅供参考

收集的泛型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<>();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章