泛型

Java泛型

泛型主要目的是为了解决ClassCastException的问题

举个栗子

package com.test;

class Point {
	private Object x ;
	private Object y ;
	public void setX(Object x) {
		this.x = x ;
	}
	public void setY(Object y) {
		this.y = y ;
	}
	public Object getX() {
		return this.x ;
	}
	public Object getY() {
		return this.y ;
	}
}
public class JavaDemo {	// 主类
	public static void main(String args[]) {	// 主方法
		Point point = new Point() ;
		point.setX(10) ;	// 自动装箱&向上转型
		point.setY(20) ;	// 自动装箱&向上转型
		int x = (Integer) point.getX() ;	// 向下转型 & 自动拆箱
		int y = (Integer) point.getY() ;	// 向下转型 & 自动拆箱
		System.out.println("x = " + x + "、y = " + y) ;
	}
}

运行结果:
运行结果图

此时,Object可以接受所有的数据类型,但是正因如此,程序会出现安全隐患

具有安全隐患的代码

package com.test;

class Point {
	private Object x ;
	private Object y ;
	public void setX(Object x) {
		this.x = x ;
	}
	public void setY(Object y) {
		this.y = y ;
	}
	public Object getX() {
		return this.x ;
	}
	public Object getY() {
		return this.y ;
	}
}
public class JavaDemo {	// 主类
	public static void main(String args[]) {	// 主方法
		Point point = new Point() ;
		point.setX(10) ;	// 自动装箱&向上转型
		point.setY("北纬20度") ;	// 向上转型
		int x = (Integer) point.getX() ;	// 向下转型 & 自动拆箱
		int y = (Integer) point.getY() ;	// 向下转型 & 自动拆箱
		System.out.println("x = " + x + "、y = " + y) ;
	}
}

运行结果:
运行结果图

此时,程序在执行"int y = (Integer) point.getY()"语句,出现安全隐患
但是,程序编译是完全可以通过的,但是执行后会出现 “ClassCastException” 异常

使用泛型,从而避免"ClassCastException"

package com.test;

class Point<T> {	// T表示Type
	private T x ;
	private T y ;
	public void setX(T x) {
		this.x = x ;
	}
	public void setY(T y) {
		this.y = y ;
	}
	public T getX() {
		return this.x ;
	}
	public T getY() {
		return this.y ;
	}
}
public class JavaDemo {	// 主类
	public static void main(String args[]) {	// 主方法
		Point<Integer> pointA = new Point<Integer>() ;
		Point<String> pointB = new Point<String>() ;
		pointA.setX(10) ;
		pointA.setY(20) ;
		System.out.println("x = " + pointA.getX() + "、y = " + pointA.getY()) ;
		pointB.setX("东30");
		pointB.setY("西30");
		System.out.println("x = " + pointB.getX() + "、y = " + pointB.getY()) ;
	}
}

运行结果:
运行结果图

此时,程序设置了泛型"T",
在main方法中实例化对象pointA (“Point pointA = new Point()”)的时候进行了Integer类型的定义
实例化对象pointB (“Point pointB = new Point()”)的时候进行了String类型的定义

注意

  1. 泛型中只允许设置引用类型,如果要操作基本类型,必须使用包装类;
  2. 从JDK1.7开始,泛型对象实例化可以简化为"Point pointB = new Point<>() ;"

引用传递

package com.test;

class Message<T> {
	private T info ;
	public void setInfo(T info) {
		this.info = info ;
	}
	public T getInfo() {
		return this.info ;
	}
}
public class JavaDemo {	// 主类
	public static void main(String args[]) {	// 主方法
		Message<String> msg = new Message<String>() ;
		msg.setInfo("今天好热") ;
		fun(msg) ;
	}
	public static void fun(Message<String> temp) {
		System.out.println(temp.getInfo()) ;
	}
}

运行结果:
运行结果图

"Message"对象"msg"定义了"String"类型, 方法"fun()"只能接收"Message< String>"类型;

此时,出现一个问题,如果程序使用了泛型,那么就不可能只是一种类型,则fun()方法应该可以接收任意类型

使用通配符"?"来解决问题

package com.test;

class Message<T> {
	private T info ;
	public void setInfo(T info) {
		this.info = info ;
	}
	public T getInfo() {
		return this.info ;
	}
}
public class JavaDemo {	// 主类
	public static void main(String args[]) {	// 主方法
		Message<String> msg = new Message<String>() ;
		msg.setInfo("今天好热") ;
		fun(msg) ;
		Message<Integer> ms = new Message<Integer>() ;
		ms.setInfo(10) ;
		fun(ms) ;
	}
	public static void fun(Message<?> temp) {
		System.out.println(temp.getInfo()) ;
	}
}

运行结果:
运行结果图

在通配符"?"的基础上,还提供两类小的通配符:

  1. ? extends 类:设置泛型的上限
    例如:"? extends Number":表示该泛型类型只允许设置"Number"或者"Number"的子类
  2. ? super 类:设置泛型的下限
    例如:"? super String":表示该泛型类型只允许使用"String"或"String"的父类

泛型接口

interface IMessage<T> {
	public String test(T t) ;
}

对于泛型接口的子类而言有两种实现方式:

  1. 在子类之中继续设置泛型定义
package com.test;


interface IMessage<T> {
	public String test(T t) ;
}
class MessageImpl<S> implements IMessage<S> {
	public String test(S t) {
		return "【测试】" + t;
	}
}
public class JavaDemo {	// 主类
	public static void main(String args[]) {
		IMessage<String> msg = new MessageImpl<String>() ;
		System.out.println(msg.test("测试"));
	}
}

运行结果:
运行结果图

  1. 在子类实现父接口的时候直接定义出具体泛型类型
package com.test;

interface IMessage<T> {
	public String test(T t) ;
}
class MessageImpl implements IMessage<String> {
	public String test(String t) {
		return "【测试】" + t;
	}
}
public class JavaDemo {	// 主类
	public static void main(String args[]) {
		IMessage<String> msg = new MessageImpl() ;
		System.out.println(msg.test("测试"));
	}
}

运行结果:
运行结果图

泛型方法

如果将泛型标记写在了方法上,那么这样的方法就被称为泛型方法

如果一个类上没有定义泛型,那么也可以使用泛型方法,举个栗子:

package com.test;

public class JavaDemo {	// 主类
	public static void main(String args[]) {	// 主方法
		Double [] result = init(1.1,2.2,3.3) ;	// 由外部设置泛型类型
		for (double temp : result) {
			System.out.print(temp + "、") ;
		}
	}
	public static <T> T[] init(T ... args) {
		return args ;
	}
}

运行结果:
运行结果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值