Java 通配符与泛型

泛型

一句话总结:对类型实现了参数化
一般使用固定字母表征,如T,K,V,E,其原理是类型擦除,在进入JVM前,这些指代字母都会被替换为Object,后面再通过强制类型转化变为期望的类型。

经典的例子:我们常用的集合类,如List中的Integer就是对参数化的类型进行赋值,将原本的类型变量转为一个固定的Integer类型。

通配符

为什么要有通配符:通配符的出现是为了解决集合无法协变的问题。
协变:协变指的就是如果 Student 是Person的子类,那么 List 也应该是 List 的子类。

Number num = new Integer(10); // compile success
ArrayList<Number> list = new ArrayList<Integer>(); // compile error

实现泛型协变和逆变主要是 extends 和 super 关键字,例如:

< ? extends T>实现泛型协变

ArrayList<? extends Number> list = new ArrayList<Integer>();

< ? super T>实现泛型逆变

ArrayList<? super Number> list2 = new ArrayList<Object>();

使用extends和super的时机
PECS原则——producer-extends, consumer-super
如果是从集合中读取元素,使用extends,因为extends确定了上界,而元素能够向上转型,所有可以得到上界类型的引用。对集合来说,集合作为生产者生产元素供读取,所以是producer-extends.

如果是向集合中写入元素,使用super,因为super确定了下界。但是在实际使用中,只可以向集合中写入元素的子类,因为只有向集合中写入元素理解为集合消费元素。

实验代码:

public class PECS_test {
    public static void main(String[] args) {
        List<Fruit> fruits = new ArrayList<>();
        List<? super Apple> fruits2 = fruits;
        List<? extends Fruit> fruits3 = fruits;

        //如果只是增加元素,集合支持自动向上转型
        fruits.add(new Apple(1,1,2));

        //编译器警告 虽然是super修饰 但是并不能直接加入它的父类
        //fruits2.add(new Fruit(1,2));

        fruits2.add(new Apple(1,2,2));

        fruits2.add(new GreenApple());
        fruits2.add(new GreenApple());

        //使用extends的,只可以读,不可以写
        //fruits3.add(new Apple(1,2,3));
        //fruits3.add(new Fruit(1,2));
        

        Fruit f = fruits3.get(0);
    }


}
class Fruit{
    public Fruit(int price, int number){
        this.price = price;
        this.number = number;
    }
    int price;
    int number;
}

class Apple extends Fruit{
    public Apple(int price, int number, int size){
        super(price, number);
        this.size = size;
    }
    int size;
}
class GreenApple extends Apple{
    public GreenApple(){
        super(1,1,1);
    }
}

泛型和通配符对比

泛型更像是个参数,一旦确定就只有一个值,通配符更加灵活,用于确定一个范围。

参考资料:
① https://www.cnblogs.com/czwlinux/p/17321493.html
②https://blog.csdn.net/WTUDAN/article/details/125781490

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值