美文网首页
Java 逆变 协变

Java 逆变 协变

作者: zhengaoly | 来源:发表于2022-03-15 16:42 被阅读0次

    List <? extend Number> xiebianList= new ArrayList<Integer>();

    表示xiebianList这个变量可以=Number的任何子类的List,例如这里可以等于Integer的ArrayList

    但是往里面添加的时候,由于Number子类不确定,所以如果添加一个Float,此时就相当于往ArrayList<Integer>里添加一个Float,而ArrayList<Integer>.add(e)要求的类型e是Integer的,显然是不合理的。所以不能对协变进行修改操作。

    但是获取是没问题的,因为获取的对象都是Number的子类

    List<? super Number>nibianList = new ArrayList<Number>();

    表示nibianList 这个变量可以=Number的任何父类的List,例如这里可以等于Number的ArrayList,也可以等于Number父类的ArrayList,如new ArrayList<Object>()

    这里王nibianList添加元素时,如果添加Number的父类,如nibianList.add(new Object());那就不合理了,因为此时nibianList.add要求参数是Number的,但是添加的确实一个object对象,相当于父类做了实参。显然是不合理的。

    如果添加Number的子类,是合理的,因为Number的父类,显然也是Number子类的父类,那么add方法的参数,实际上是子类做实参,是没有问题的。

    class Fruit{
    
    }
    class Apple extends Fruit{
    
    }
    
    class PearApple extends Apple{
    
    }
    
    public class TestNibianxiebian {
        public static void main(String[] args) {
            List<Apple> apples = new ArrayList<>();
            List<Fruit> fruits = new ArrayList<>();
            List<PearApple> pearApples = new ArrayList<>();
            fruits.add(new Apple());
            fruits.add(new PearApple());
    
            List<? extends Fruit> xiebian = apples;//只读
            xiebian = pearApples;
    
            List<? super Apple> nibian = fruits;//可以等于apple及apple的父类
            nibian = apples;//apple的父类容器都是合法的
            nibian.add(new PearApple());//可以添加apple及子类对象
            nibian.add(new Apple());
            //nibian这个变量=父类的容器,也就是add的形参是apple或者apple的父类,添加父类的不合法的,但是添加apple的子类是合法的,因为子类实参赋值给父类是类型安全的转换
    //        nibian.add(new Fruit());
        }
        public void test1(List<? extends Number> data){
    
        }
        public void test(List<? super Number> data){
    
        }
    }
    

    相关文章

      网友评论

          本文标题:Java 逆变 协变

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