泛型的深入理解和案例解析(2)---上下界和通配符

0. 引言

   在上一小节《泛型的深入理解和案例解析(1)—应用篇》我们知道了泛型的基本使用,并且也注意到泛型仅支持类类型,而不支持基本类型。
   那么问题出来了,类类型之间有继承关系,泛型是不是支持呢,本节就将对这个问题进行深入分析。

1. 一个问题引出上下界

  问题1:比如一个ArrayList列表,要往里边放入数字,但是不确定Integer Long …,方便后续取出值计算。这个时候怎么使用泛型?
  实现见如下代码:

class ListNum<E extends Number> extends ArrayList {
// 这里需要继承ArrayList并对泛型进行一下限制即可
}

  使用如下效果:

ListNum<Integer> listIntegers = new ListNum<Integer>(); //编译通过
ListNum<String> listStrings = new ListNum<String>(); //编译失败 Bound mismatch

2. 一个问题引出通配符

  问题2:有一个函数,只接收包含Number的ArrayList,但不确定具体是哪个数字类型?
  这时候就引入了通配符"?"。
  我们在正则表达式中见过通配符,就是能够匹配某一类字符的通用表示,"?"也是这个意思。
  代码实现如下:

private static void set(ArrayList<? extends Number> list) {
		
}
set(new ArrayList<Integer>());
		
set(new ArrayList<String>());// 报错,参数不匹配

3. 上下界

  我们知道泛型除了有extends 还有一个super,他们两个什么区别?
定义几个类型如下:

	class smallCat extends cat {
        
    }
    
	class cat extends Animal {
        @Override
        public void run() {
            System.out.println("cat run");
        }
    }

    class dog extends Animal {
        @Override
        public void run() {
            System.out.println("dog run");
        }
    }

    class Animal {
        public void run() {
        }
    }

  考察extends和super是什么性质。

  1. extends继承关系,继承父类的方法,可以向上转型为父类而不会出现错误。
    使用场景:
    (1) 泛型指代的参数类型,都拥有某个方法,或者都具有父类的某个属性,可以用做多态使用的时候;如下代码所示:
	private void AnimalRun(ArrayList<? extends Animal> animals) {
    	animals.get(0).run();
	}

(2) 集合使用extends,对get赋值是开放的,对add是关闭的。因为允许存储某个类的子类,这样在取出的时候,赋值给父类引用,不会出现类型异常。但是add的时候,并不确定该集合是具体哪个类型,所以不允许。
代码如下:

		ArrayList<? extends Animal> animals = new ArrayList<>();
        animals.add(new cat()); //编译报错
        Animal animal = animals.get(0); // 转型正确
  1. super 相当于指定某个类的所有可能父类,而父类和子类显然没有必然的关系。
    使用场景:
    (1) 相较extends,super对get是关闭的,因为不确定集合内是具体哪个类型,取出赋值容易出现转型错误;而add是开放的,因为只要保证是某个类的子类即可。
    其实super实际中用的比较少,代码如下:
		ArrayList<? super cat> animals = new ArrayList<>();
        animals.add(new cat());
        animals.add(new smallCat()); 
        animals.add(new Animal()); //报错

注意:super只能 “?”使用,T 是不支持的。

4. Producer Extends Consumer Super(PECS 原则)

  只读不可写时,使用List<? extends Fruit>:Producer
  只写不可读时,使用List<? super Apple>:Consumer

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值