Java 泛型通配符上下界理解及应用

一.通配符的应用

实践检验真理,所以在说明通配符上下界的理解的时候,先说明下什么时候使用通配符

关于泛型
类型通配符的作用是为了代替泛型类的类型实参

当我们使用泛型类作为参数时,我们不想固定具体的泛型类型实参,而是想接收任意类型,或者某个类及其子类或超类类型作为类型实参,这个时候就需要使用通配符了,使用泛型类<?>作为类型实参
总结来说通配符解决的问题就是:类B是类A子类,但是泛型类<B>不是泛型类<A>的子类,但是我们又想有这么个类型能同时接收泛型类<B>泛型类<A>类型作为参数的问题

通配符类型

  • 无边界通配符:<?>
    使用无边界通配符可以让泛型接收任意类型的数据

  • 上边界通配符 :<?extends 具体类型 >
    使用固定上边界的通配符的泛型可以接收指定类型及其所有子类类型的数据,这里的指定类型可以是类也可以是接口

  • 下边界通配符 :<? spuer 具体类型>
    所有固定下边界的通配符的泛型可以接收指定类型及其所有超类类型的数据。

通配符无法同时指定上下边界

举个栗子
我们常用的List就是一个泛型类,以java.lang.Number类及其子类,超类作为类型实参,具体继承关系如下:


看下下面这段代码:

private List<? extends Number> data;

    private void test() {
        List<Number> numbers = new ArrayList<>();
        List<Integer> integers = new ArrayList<>();
        //List<Number> data = integers; //编译报错
        data = numbers;
        data = integers;
    }

显然虽然IntegerNumber的子类,但是List<Integer>并不是List<Number>的子类,所以List<Integer>类型的变量不能直接赋值给List<Number>的变量。这时候通配符就起到作用了List<? extends Number>可以看做是List<Integer>List<Number>的父类型,它可以接收Number类或者其子类型作为类型形参的泛型数据。
所以当我们要在一个方法或者类中接收不固定类型实参的泛型数据,可以考虑使用通配符

二.关于通配符的上下界

1. 无边界 和 上边界通配符

使用无边界和上边界通配符的泛型不能赋值(除了null),可以取值,但是只能去指定的类型及其超类类型(无边界只能取Object类型数据)

(无边界其实上边界就是Object)

List为例:下面这段代码当我们用List<?>或者List<? extends Number>add数据时发现都会编译报错。
为什么:根据上面应用的结论,List<Integer>List<Long>List<Double>这些类型可以理解为List<?>或者List<? extends Number>的子类型。
这时候List<?>或者List<? extends Number> add时候不知道到底要往List<Integer>List<Long>List<Double>还是其他Number子类型的Listadd数据的是IntegerLong还是Double类型。这么操作可能会引发类型不一致的问题,这显然和泛型的设计是相悖的。因此Java为了保证类型一致,是不允许这么操作的。但是null是所有引用类型都有元素,所有可以add成功。

List<?> data = new ArrayList<>();
List<?> data = new ArrayList<>();
data.add(new Object()); //编译报错
data.add(10);  //编译报错
data.add(null);

 List<? extends Number> numbers = new ArrayList<>();
numbers.add(10); //编译报错
numbers.add(new BigDecimal(20)); //编译报错
numbers.add(null);

在看一下get取值方法:
下面代码可以看出(忽略运行错误啊,只是为了说明泛型编译问题):get方法是可以取到指定类型及其超类型的数据。

List<?> data = new ArrayList<>();
Object object = data.get(0);

List<? extends Number> numbers = new ArrayList<>();
Number number = numbers.get(0);
Object number2 = numbers.get(0);
2.下边界通配符

与无边界和上边界通配符相反,下边界通配符只能取Object类型的数据,但可以赋值,只要是指定类型或者其子类型都能成功赋值

还是以List类为例,代码如下,对应到List里面就是add指定类型及其子类型数据时可以正常编译通过,但是get方法不能编译通过
为什么:因为LongBigDecimalFloat都是Numer的子类,根据之前的结论? super Number代表可以接收指定类型及其父类型的数据,所以List<? super Number>可以理解为List<Number>或者List<Object>的父类型,显然List<Number>或者List<Object>是可以add Numer的子类型数据的。但是get的时候因为不知道具体是
List<Number>还是List<Object>或者是之间的什么类型,所以只能get所以类型的父类型Object`类型

List<? super Number> data = new ArrayList<>();
data.add(10);
data.add(new BigDecimal(1000));
data.add(10.07f);
data.add(new Object()) //编译报错

Object object = data.get(0);
Number number = data.get(0); //编译报错

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容