Java泛型学习笔记

Java泛型初级学习笔记

仅为笔记,具体参考廖雪峰Java教程

泛型中我平常使用最多的就是集合,例如List,Map,Set。

ArrayList举例,在业务中使用时可以传入任何类型。

如:

ArrayList<String> arrayList = new ArrayList<>();

ArrayList<Integer> integerArrayList = new ArrayList<>();

而传入的是什么类型,在你调用时就是什么类型。

String str = arrayList.get(0);

Integer num = integerArrayList.get(0);

这样可以省去大多数不必要的装箱和拆箱,甚至有时不小心还会出现ClassCastException

这是泛型最直观的好处,再去看看ArrayList的源码。

这里的E的意思是指,可以传入任何类型,当然理所当然的在你调用该类的其他方法时,也会使用到这个泛型。

如最典型的get方法:

public E get(int index) {
    //判断是否下标越界
    rangeCheck(index);
	//调用内部封装数组的指定下标的所在元素
    return elementData(index);
}

在这里就会根据你传入时的数据类型来传出指定类型的数据。

但是在这里需要注意一点,在JVM中,它并不知道你做了这些处理的,这些工作都是编译器帮你做的。

来举个栗子,就比如上面的

ArrayList<Integer> integerArrayList = new ArrayList<>();

实际上在运行中,它是

ArrayList integerArrayList = new ArrayList<>();

这就是常说的泛型擦除

编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息。

编译器内部永远把所有类型T视为Object处理,但是,在需要转型的时候,编译器会根据T的类型自动为我们实行安全地强制转型。

这就代表在你拿取数据时所调用的方法,其实都是经过了一个转型的过程。

Integer num = (Integer) integerArrayList.get(0);

只不过这些并没有让你看见。

在这里,廖雪峰老师在博客里指出了它的四个局限。

  • <T>不能是基本类型,例如int,因为实际类型是ObjectObject类型无法持有基本类型。
  • 无法取得带泛型的Class
  • 无法判断带泛型的类型。
  • 不能实例化T类型。

可以通过廖雪峰Java教程去看详细解释。

这里要注意泛型的一个严重的问题,也是文章中指出的。

ArrayList<Integer>向上转型为ArrayList<Number>List<Number>,虽然IntegerNumber的子类,但与此同时Float也是Number的子类,若是传入一个Float类型的参数,拆箱时是会出现ClassCastException的,当然,编译器会直接禁止这种行为。

但是Java在这里提供了另一种方式,也就是extends通配符,看一下它在代码中的使用。

在这里插入图片描述
这是ArrayListaddAll方法,可以批量添加的一个方法,只要满足了传入类型是当前类型的子类的条件,就可以传入该参数。

但是在读取时,得以最初的父类泛型为准,因为它并不知道传入的类型是哪个子类,也就是说,可能还会有拆箱的一步。

在写入时使用该通配符显然也是不行的,若一个Class<? extends Number>传入Class<Double>显然是可以的,但是Double是不接受setInteger类型的。

相反,必然也会有可以传入父类型的通配符super,它的作用正好相反,可以在此传入所传类型的父类。

虽说在传入时可以传入父类型,但在读取时却只有Object类型能接收,因为它同样也不知道传入的是哪个父类,Object类型例外,是因为它在这里是所有对象的父类,所以可以用来接收任何值。

因为在读取时,方法的签名会变成

? super T get(int index);

若传入T是Integer类型,用Number接收时,编译器无法将Number类型转换为Integer类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值