一篇文讲明白Java泛型

本文深入探讨Java泛型,包括为何使用泛型以提高类型安全性和代码复用,泛型在接口、类和方法中的应用,以及泛型擦除的概念和影响,如类型变量不能用基本类型、不能使用instanceof等。同时,介绍了PECS原则帮助更好地使用泛型。
摘要由CSDN通过智能技术生成

泛型(Generic)是JDK5引入的一种参数化类型特征,是Java编程语言的强大功能。它们提高了代码的类型安全性,使你在编译时可以检测到更多错误。泛型通过在编译时检测到更多错误来增加代码的稳定性。

在这里插入图片描述

1. 为什么要使用泛型

简而言之,泛型在定义类,接口和方法时使类型(类和接口)成为参数。与方法声明中使用的更熟悉的形式参数非常相似,类型参数为你提供了一种使用不同输入重复使用相同代码的方法。区别在于形式参数的输入是值,而类型参数的输入是类型。

2. 泛型的好处

  • 代码更健壮(只要编译器没有警告,那么运行期就不会出现ClassCastException)
  • 代码更简洁(不用强转)
  • 代码更灵活,复用

3. 泛型长什么样

3.1. 泛型接口

public interface Plate<T>{
	public void set(T t);
	public T get();
}

3.2. 泛型类

public class AIPlate<T> implements Plate<T>{
	private List<T> items = new ArrayList<T>(10);
}

3.3. 泛型方法

	public <T> AIPlate<T> getAIPlate(){
		return new AIPlate<T>();
	}

4. 泛型擦除

4.1. Java泛型的原理?什么是泛型擦除机制?

Java的泛型是JDK5新引入的特性,为了向下兼容,虚拟机其实是不支持泛型的,所以Java实现的是一种伪泛型机制,也就是说Java在编译器擦除了所有的泛型信息,这样Java就不需要产生新的类型到字节码,所有的泛型类型最终都是一种原始类型,在Java运行时根本就不存在泛型信息。

4.2. Java编译器具体是如何擦除泛型的?

  1. 检查泛型类型,获取目标类型
  2. 擦除类型变量,并替换为限定类型
    如果泛型类型的类型变量没有限定(< T >),则用Object作为原始类型
    如果有限定< T extends XClass>,则用XClass作为原始类型
    如果有多个限定< T extends XClass1 & XClass2>,则使用第一个边界XClass1作为原始类
  3. 在必要时插入类型转换以保持类型安全
  4. 生成桥方法以在扩展时保持多态性

4.3. 使用泛型以及泛型擦除带来的影响(副作用)

4.3.1. 泛型类型变量不能使用基本数据类型?

比如没有ArrayList< int >,只有ArrayList< Integer >,当类型擦除后,ArrayList的原始类型中的类型变量< T >替换成了Object,但Object类型不能存放int值。
在这里插入图片描述

4.3.2. 不能使用instanceof运算符

因为擦除后,ArrayList只剩下原始类型,泛型信息String不存在了,所以没法使用instanceof
在这里插入图片描述

4.3.3. 泛型在静态方法和静态类中的问题

因为泛型类中泛型参数的实例化是在定义泛型类型对象(比如ArrayList< Integer >)的时候指定的,而静态成员是不需要使用对象来调用,所以对象都没创建,如何确定这个泛型参数是什么。
在这里插入图片描述

4.3.4. 泛型类型中的方法冲突

因为擦除后两个equals方法变成一样的了。
在这里插入图片描述

4.3.5. 没法创建泛型实例

因为类型不确定。
在这里插入图片描述

4.3.6. 没有泛型数组

因为数组是协变,擦除后就没法满足数组协变的原则。
协变:例如A extends B,那么A[ ]的父类是B[ ]。
在这里插入图片描述

5. Java泛型PECS原则

  • 如果你只需要从集合中获得类型T,使用<? extends T>通配符
  • 如果你只需要将类型T放到集合中,使用<? super T>通配符
  • 如果你既要获取又要放置元素,则不使用任何通配符。

PESC即Producer extends Consumer super。

非限定通配符:AClass<?>是一个未知的泛型类型,等价于AClass<? entends Object>
限定通配符:AClass<? extends T> 上界;AClass<? super T> 下界。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值