美文网首页泛型程序鱼学习笔记Java学习笔记
java泛型上限通配符和下限通配符

java泛型上限通配符和下限通配符

作者: 程序鱼 | 来源:发表于2016-10-25 00:21 被阅读345次

    <? extends T>上限通配,表示?是T的一个未知子类。
    <? super T>下限通配,表示?是T的一个未知父类。

    下面来分别讲一下

    1. <? extends T> 上限通配

    这里?表示一个未知的类,而T是一个具体的类,在实际使用的时候T需要替换成一个具体的类,表示实例化的时候泛型参数要是T的子类。

    举个例子
    我们有一个水果类

    /**
     * 水果类
     */
    public abstract class Fruit {
        public abstract void eat();
    }
    

    然后创建两种水果继承水果类Fruit

    /**
     * 苹果类
     */
    public class Apple extends Fruit {
        @Override
        public void eat() {
            System.out.println("我是苹果,我是酸酸甜甜的");
        }
    }
    
    /**
     * 香蕉类
     */
    public class Banana extends Fruit {
        @Override
        public void eat() {
            System.out.println("我是香蕉,我是软软的");
        }
    }
    
    

    我们还需要一个吃瓜群众

    /**
     * 吃瓜群众
     */
    public class People<T extends  Fruit> {
    
        public void eatFruit(T t){
            t.eat();
        }
    }
    

    请注意定义People类的时候我们使用了泛型上限表示<T extends Fruit>
    我们创建一个类测试一下

    public class Test {
        public static void main(String[] args) {
            People<Apple> p1 = new People<>();
            p1.eatFruit(new Apple());
            
            People<Banana> p2 = new People<>();
            p2.eatFruit(new Banana());
        }
    }
    
    输出结果.png

    若此时我们创建一个橙子类,但不继承自Fruit父类

    /**
     * 橙子类
     */
    public class Orange {
        public void eat() {
            System.out.println("我是橙子,我是酸酸的");
        }
    }
    

    编译时期就会报错,提示Orange不在范围内,应该要继承Fruit类


    编译报错.png

    2. <? super T> 下限通配

    这里?表示一个未知的类,而T是一个具体的类,在实际使用的时候T需要替换成一个具体的类,表示实例化的时候泛型参数要是T的父类。

    例如

    public static void addNumbers(List<? super Integer> list) {
        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }
    }
    

    这里表示我们调用这个方法时可以传入参数是Integer或者Integer的父类,例如:

    public class TestLowerBounded {
        public static void addNumbers(List<? super Integer> list) {
            for (int i = 1; i <= 10; i++) {
                list.add(i);
            }
        }
    
        public static void main(String[] args) {
            List<Integer> list1 = new ArrayList<>();
            addNumbers(list1);
    
            List<Number> list2 = new ArrayList<>();
            addNumbers(list2);
    
            List<Object> list3 = new ArrayList<>();
            addNumbers(list3);
    
            List<String> list4 = new ArrayList<>();
            //编译错误,因为String不是Integer的父类
            //addNumbers(list4);
        }
    }
    

    Number和Object都是Integer的父类,所以编译通过,而String不是Integer的父类,编译报错。


    以上就是泛型上限通配符和下限通配符的作用了,知识点比较小,希望可以一点一点积累,和大家一起进步。

    相关文章

      网友评论

      • b949fd54aabe:如果Fruit 不是抽象类,也是可以作为People的泛化类型的,也就是 <T extends Fruit> 的地方,也可以让 T 为 Fruit,前提是Fruit可以实例化
      • 042a0e1be73f:标题字都错了。。。
        程序鱼:@iOSwift 确实。。。我马上改

      本文标题:java泛型上限通配符和下限通配符

      本文链接:https://www.haomeiwen.com/subject/tlncuttx.html