Java 泛型通配符详解

后端 潘老师 3个月前 (11-28) 67 ℃ (0) 扫码查看

本文主要讲解关于Java 泛型通配符详解相关内容,让我们来一起学习下吧!

1、首先要知道泛型是什么?

  • 泛型就是一种不确定的数据类型。本质是参数化类型。
  • 没有泛型的时候,通过对类型 Object 的引用,假设时子类String实现,那么则编译器不会对静态类型Object做限制,输入可以是任意类型,比如Integer。然后输出时,强制类型转换为实现的子类String时,就会报错。这存在安全隐患
  • 泛型的好处就是编译的时候能够检查类型安全,并且所有强制转换都是自动隐式的
  • 我创建一个List< String>类型的引用,用ArrayList< String>()赋值。那么编译器检查我输入的会是不是String
//正确
List<String> listObject = new ArrayList<String>();
listObject.add("");


2、想参照父类声明子类实例化写泛型类似的功能-❌

  • 不能如下写,虽然A extends B 但是ArrayList< A>和ArrayList< B>,没有一毛钱关系,不可能赋值成功。

//父类声明子类实现,那么运行时是实际类型是子类右边,编译时是静态类型是父类左边,
Object object = new String();  


//会报错 List<String> listObject = new ArrayList<Object>();
//会报错  List<Object> listObject2 = new ArrayList<String>();

1.3、泛型通配符解决了上述问题

  • 声明一个水果及其子类都能用的盘子,然后实现时,用苹果具体化。先看一个上述的一个❌具体的错误用法
//声明一个水果盘子,想装点水果,用苹果盘子去赋值是不行的,也就是说苹果盘子不是水果盘子。
//会报错 Plate<Fruit> p=new Plate<Apple>(new Apple());
  • 那么我声明一个水果及其子类都能用的盘子,然后实现时,用苹果具体化,该怎么办呢?
Plate<? extends Fruit> p1 = new Plate<Apple>(new Apple());
  • 那么我定义一个水果及其父类类都能用的盘子,然后用食物,也就是其父类去赋值当然是可以啦
Plate<? super Apple> p2=new Plate<Fruit>(new Fruit());

<? extends ClassType>、<? super ClassType>中get add方法被限制的原因

  • 问号是通配符,用在声明引用类型的尖括号里,目的解决“苹果的盘子”不是“水果的盘子”之类的问题
//定义一个水果盘子,用苹果盘子去赋值是不行的,也就是说苹果盘子不是水果盘子。
//会报错 Plate<Fruit> p=new Plate<Apple>(new Apple());

//那么我定义一个水果及其子类都能用的盘子,然后用苹果也就是水果的子类去赋值当然可以
Plate<? extends Fruit> p1 = new Plate<Apple>(new Apple());

/**
 * <? extends ClassType> 不能进行set()或List中的add()操作,也就是不能执行参数列表中含有T的方法。
 */

//错误p1.set(new Apple());
//为什么禁用我往盘子里加东西呢?
//因为编译时候,静态类型是左边的。p1在编译时,我只知道类型是Fruit及其子类。运行时到底有多小我压根不知道,实际又要Apple类型,我整个GreenApple咋办。那么明显会出错,所以禁用。
//所以入参不能是泛型

//返回值只能是Fruit,一样是编译时,看左边。我只知道extend Fruit,传入最大辈分Fruit准没错。传入父类也没错,因为子转父嘛
Fruit fruit = p1.get();


/**
 *
 *  <? super ClassType>执行get()操作会返回一个Object,也就是返回值为T的方法会返回一个Object。set只能设置最小备份 也就是super后的内容
 */
//那么我定义一个水果及其父类类都能用的盘子,然后用食物,也就是其父类去赋值当然是可以啦
Plate<? super Apple> p2=new Plate<Fruit>(new Fruit());
//编译时,静态类型 看左边,我只知道装的东西是Apple或它的父类,但是到底多大,要是比实际类型更大岂不是出错,那么我就取最小值吧
p2.set(new Apple());
//我只知道比Apple大,反正传Apple不会出错
Object object = p2.get();

以上就是关于Java 泛型通配符详解相关的全部内容,希望对你有帮助。欢迎持续关注潘子夜个人博客(www.panziye.com),学习愉快哦!


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/11940.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】