第十一章 泛型 ① 笔记

1. 内容回顾

1.1 课前测试
1.2 上节内容

在这里插入图片描述

2. 本章重点

2.1. 泛型产生的意义
2.2. 泛型的使用
2.3. 泛型擦除
2.4. 通配符?的使用
2.5. 受限泛型
2.6. 泛型与子类继承的限制
2.7. 泛型方法

3. 具体内容

3.1 泛型产生的意义

泛型是在JDK1.5之后增加的新功能,泛型Generice
 泛型产生的意义,为了保证数据的安全性
 泛型的基本使用,由外部指定其具体的操作类型

3.2 使用泛型类

为什么要使用泛型?有如下需求:
设计一个可以表示出坐标点的类,坐标又X和Y组成,坐标的表示方法有以下三种
 整数表示: x=100,y=30
 小数表示:x=10.5,y=10.5
 字符串表示: x=“东经180度”, y = “北纬200度”
如何设计这个类?
我们要定义一个表示坐标点的类,根据描述的内容,我们需要在类中定义两个属性x,y。
而这两个属性的取值,可以是数字,小数和字符串

package com.test5;

public class Pointer<T>{
	private T x; //表示x坐标
	private T y; //表示y坐标
	
	public T getX() {
		return x;
	}
	public void setX(T x) {
		this.x = x;
	}
	public T getY() {
		return y;
	}
	public void setY(T y) {
		this.y = y;
	}
}
public static void main(String[] args) {
	Pointer<Integer> pt=new Pointer<Integer>();
	pt.setX(100);
	pt.setY(200);
	int x = pt.getX();
	int y = pt.getY();
	System.out.println("x:"+x+" y:"+y);
}

构造方法的参数使用泛型

public class Pointer<T>{
	...
	public Pointer(T x,T y){
		this.x=x;
		this.y=y;
	}
	...
}

在泛型类中同时指定多个类型

package com.test5;
public class Notepad<K,V> {
	private K key;
	private V value;
	public Notepad(K key,V value){
		this.key=key;
		this.value=value;
	}
	public K getKey() {
		return key;
	}
	public void setKey(K key) {
		this.key = key;
	}
	public V getValue() {
		return value;
	}
	public void setValue(V value) {
		this.value = value;
	}
	@Override
	public String toString() {
		return "Notepad [key=" + key + ", value=" + value + "]";
	}
}

	public static void main(String[] args) {
		Notepad<String, Integer> np = new Notepad<String, Integer>("张三",80
		System.out.println("姓名:"+np.getKey());
		System.out.println("年龄:"+np.getValue());
	}

3.3 泛型擦除

java中的泛型只在源代码中存在,在运行时,Java不会保留范型。

List<String> listStr = new ArrayList<>();
listStr.add("aaa");
listStr.add("xxx");
//泛型被擦除
List list = listStr;
list.add(100);
list.add(200);

为什么可以这么玩?因为Java的范型只存在于源码里,编译的时候给你静态地检查一下
范型类型是否正确,而到了运行时就不检查了。上面这段代码在JRE(Java运行环境)
看来和下面这段没区别:

List listStr = new ArrayList();
listStr.add(100);
listStr.add(200);

为什么要类型擦除?
为了向下兼容。
Java 5才引入了范型,在此之前都是没有范型的。当时引入范型只是为了解决遍历集合
的时候总要手动强制转型的问题。

3.4 泛型通配符?

在程序开发中对象的引用传递是最常见的,但是如果方法参数是泛型类对象,则传入的
泛型数据必须匹配才可以,否则是无法传递的。

public class Info<T>{
	private T var;
	public T getVar() {
		return var;
	}
	public void setVar(T var) {
		this.var = var;
	}
	@Override
	public String toString() {
		return "Info [var=" + var + "]";
	}
}

在这里插入图片描述
改为String类型的泛型之后,则可以传递参数
在这里插入图片描述
另外如果方法的参数没有指定泛型的时候,这种情况也可以传递参数。此时使用擦除泛
型的特性。
在这里插入图片描述
另外一种接受泛型参数的方法是,使用?通配符设置泛型类型

public class Test {
	public static void main(String[] args) {
		Info<String> i=new Info<String>();
		i.setVar("张无忌");
		fun(i);
	}
	public static void fun(Info<?> info){
		System.out.println(info);
		//使用通配符?可以接受任意泛型参数,但是此时泛型对象,不能修改数据
		//info.setVar("aaa");
	}
}

3.5 受限泛型

在引用传递的过程中,泛型操作也可以设置一个泛型对象的范围上限和范围下限,范围
上限使用extends关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的
子类,而范围下限使用super进行声明,表示参数化的类型可能是所指定的类型,或者此
类型的父类型,直至Object类型。

3.5.1 设置泛型上限
public class Info<T> {
	private T var;
	public T getVar() {
		return var;
	}
	public void setVar(T var) {
		this.var = var;
	}
	@Override
	public String toString() {
		return "Info [var=" + var + "]";
	}
}
	
public class Test {
	public static void main(String[] args) {
		Info<Integer> ii=new Info<Integer>();
		ii.setVar(100);
		fun(ii);
		Info<Double> id = new Info<Double>();
		id.setVar(12.234);
		fun(id);
	}
	//接受info对象,范围上限设置为Number,所以只能接受数字类型
	public static void fun(Info<? extends Number> info){
		System.out.println(info);
	}
}

也可以直接在定义类的时候,设置好泛型范围

package com.test7;
public class Info<T extends Number> {
	private T var;
	public T getVar() {
		return var;
	}
	public void setVar(T var) {
		this.var = var;
	}
	@Override
	public String toString() {
		return "Info [var=" + var + "]";
	}
}
3.5.2 设置泛型下限

当使用的泛型只能在本类及其父类类型上应用的时候,就必须使用泛型的范围下限配
置。(不能在定义类的时候使用下限定义,只能用?方式定义)

public class Test {
	public static void main(String[] args) {
		Info<String> i1 = new Info<String>();
		i1.setVar("张三");
		fun(i1);
		Info<Object> i2=new Info<Object>();
		i2.setVar(100);
		fun(i2);
	}
	public static void fun(Info<? super String> i){
		System.out.println(i);
	}
}

一个类的子类可以通过对象多态性,为其父类实例化。但是在泛型操作中,子类的泛型
类型是无法使用父类的泛型类型接受,例如: Info 不能使用 Info接受

3.6 泛型方法

针对某个方法设置泛型

public class Info2 {
	//泛型方法,无返回值
	public <T> void test(T val){
		System.out.println(val);
	}
	//返回字符串的泛型方法
	public <T> String test2(T val){
		return val.toString();
	}
	//返回任意类型的泛型方法
	public <T> T test3(T val){
		return val;
	}
}

public class Test2 {
	public static void main(String[] args) {
		Info2 i1 = new Info2();
		i1.test("100");
		i1.test(100);
		String s1 = i1.test2("aaa");
		String s2 = i1.test2(100);
		System.out.println(s1);
		System.out.println(s2);
		int s3 = i1.test3(100);
		String s4 = i1.test3("bbb");
		System.out.println(s3);
		System.out.println(s4);
	}
}

4. 本章总结

 泛型的意义
 泛型的使用
 泛型擦除
 通配符的使用
 受限泛型
 泛型与子类继承的限制
 泛型方法

5. 课后作业

课堂代码3遍以上练习
预习数据库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值