java中泛型的使用(二)

本文深入探讨Java泛型的工作原理,包括类型擦除的概念及其如何影响泛型在运行时的表现,以及如何通过边界限制来安全地使用泛型,避免类型转换错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

前面讲述了一些泛型类,泛型接口,泛型方法的基础,这些并不是很重要,熟悉一些原理才是比较好的。


类型擦除


关于类型擦除这个东西,java中的泛型很多人都成为“伪泛型”,因为java中在编译的时候都是通过类型擦除来实现泛型。

怎么说呢,什么叫类型擦除呢?

下面这种情况:

我们这里通过T传入实际的对象,比如传入一个String类型,但是他会将其转成Object类型,凡是代码中有T的地方都是Object,而在返回T时就会自动插入T的实际类型进行强制转型。

我不知道jvm的发明者为什么要这样实现泛型,实现泛型的方式很多种。

如果这样操作的话,运行时其实根本不知道有泛型的存在,因为都是在编译的时候插入了代码进行类型的转换。

 

public class parent<T>{
	public void d() {
		System.out.println("d");
	}
}

这样我们不知道T具体是什么的话,就根本不能进行有关T的实际方法变量的使用了。比如

创建T的对象就会出错,因为根本不知道T有没有无参构造器。

刚才提到了,既然底层是通过一些转换成Object对象实现的,那么我们也可以通过手动的联系Object对象来实现

比如,既然不能创建对象,同时也不能创建T的数组,我们就可以这样

当然这样还是访问不了传进来的具体T类中的方法,这也是没有办法呀,这就是类型擦除带来的麻烦,但是呢,也并不是没有办法啦,可以通过边界的确定来限制T的方法,比如这里传入的T编译器能够确定肯定是Object和Object的子类对吧,所以它的边界就是Object,没有比Object更大的类了。

 

 


边界限制


我不知道专业的术语是什么,毕竟英文文献里面的东西,我也不知道怎么翻译了,前面类型擦除其实自动限制了边界是Object,这里我们就是用通配符来实现边界限制,分为上边界限制,和下边界限制,分别是?extends ...和?super ....

 

? extends ....

这里的上边界通配符,主要将?的内容限制在...类的下面

//比如下面这种
public class a{
    public static void main(String[] args){
        List<? extends parent> p = new ArrayList<son>();

    }
}

这里要说的就是这个代码片段呢,它看起来没啥错误,将边界限制在了parent以下,也就是说不用达到Object那种高度,我们通过这个泛型的表面对象使用上边界parent的里面所有方法。就像之前的限制在了Object一样了。

但是这里又造成了一个问题了,我们不值到传进来的是啥,也就是?不知道是啥,当我们使用add添加元素时,不知道啥,而java中没有自动向下转型,只有强制向下转型,编译器就认为不能向里面添加未知元素。这里怎么说呢,右边是ArrayList也就是实际在堆中开辟的对象,里面传入的也是son,左边虽然是继承的parent类型,但是parent的子类有很多,如果贸然去传入任何一个子类对象,运行时可能会出错,所以在这种不确定的情况下,干脆就让其不能再实现add方法。而又因为List是接口,调用p的add方法时,实际会调用ArrayList的add方法了。这时候是不是会起冲突

但是取出元素是可以的,因为返回的是T,传入的对象,也绝对是T的子类,可以自动向上转型。

 

? super ...

public void d() {
		
		List<? super parent> a = new ArrayList<parent>();
		a.add(new son());
}

这个代码呢,就可以实现了add了,因为这个super限定了必定时parent的父类,所以我们add的只要时parent的子类都可以了。因为这里都可以向上转型为parent,可以确定为安全的。

但是get时parent tParent = (parent) a.get(1);就要这样强制转换为tParent了

 

 

 

感悟

这里我想说的感悟就是,不管这个怎么变,我觉得都是由于一点引起的。

就是java中的自动向上转型和强制向下转型限制的各种关系。也就是不能能自动向下转型

比如?extends.. 由于不知道传入的类型具体是什么,不能自动向下转型,而导致编译器报错,这个也是没有办法的,而对于?super...这种情况,也是由于不能自动向下转型,需要强制向下转型,使用get方法才可以。

泛型的注意点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小满锅lock

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值