java - add()操作在 "? extends"和 "? super"的区别

标签 java generics

package test16;

import java.util.ArrayList;
import java.util.List;

class A {
}

class B extends A {
}

public class Test1 {
    public static void main(String[] args) {
        List list1 = new ArrayList();
        List<A> list2 = new ArrayList<A>();
        List<A> list3 = new ArrayList<>();
        List<A> list4 = new ArrayList<B>();

        List<? extends A> list101 = new ArrayList<A>();
        List<? extends A> list102 = new ArrayList<B>();

        List<? extends A> list5 = new ArrayList<>();
        A getA = list5.get(0);// return A
        list5.add(new A());// error
        list5.add(new B());// error
    }
}

? extends :所有 add() 错误。

package test17;

import java.util.ArrayList;
import java.util.List;

class A {
}

class B extends A {
}

public class Test1 {
    public static void main(String[] args) {
        List list1 = new ArrayList();
        List<B> list2 = new ArrayList<B>();
        List<B> list3 = new ArrayList<>();
        List<B> list4 = new ArrayList<A>();

        List<? super B> list101 = new ArrayList<A>();
        List<? super B> list102 = new ArrayList<B>();

        List<? super B> list5 = new ArrayList<>();
        Object object = list5.get(0);//return Object
        list5.add(new A());// error
        list5.add(new B());// ok
    }
}

? super : add() 运行正常。

<小时/>

我想知道通用设计器是出于什么考虑,extends根本不能加,super可以加

但是 stackoverflow 没有找到答案。

非常感谢!

最佳答案

Java 泛型中的扩展通配符。

private static double sum(Collection<? extends Number> numbers) {
double result = 0.0;

for (Number num : numbers) result += num.doubleValue();

return result;
}

上述方法的通配符具有 <? extends Number> 的概念。编译器将允许传递 Number 子类型的集合。但是,您无法将元素添加到使用扩展通配符声明的集合中。

List<? extends Number> numbers = new ArrayList<Integer>();
numbers.add(123); // COMPILE ERROR 

否则,我们可以将 double 添加到仅接受整数的集合中。

Java泛型中的 super 通配符。

public static void append(Collection<? super Integer> integers, int n) {
for (int i = 1; i <= n; i++) {
    integers.add(i);
}
}

在上面的方法中,您可以限制方法中添加的元素为 Integer 类型,而我们也希望接受 Integer 父类(super class)型的集合,因为将整数添加到数字集合中是完全合法的。

List<Number> numbers = new ArrayList<Number>();
append(numbers, 5);
numbers.add(6.789);

System.out.println(numbers);

super 通配符背后的想法:(使用通配符声明的类型<? super T>)

  1. 它可以接受任何 T 的父类(super class)型
  2. 我们可以向集合中添加元素。但是类型仅限于 T
  3. 它不能传递给具有使用扩展通配符声明的参数的方法。

Generics with extends and super

关于java - add()操作在 "? extends"和 "? super"的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60563215/

相关文章:

generics - 接受受多个特征中的任何一个约束的参数的函数

java - 原始类型没有警告

c# - 使用具有泛型类型的解析方法?

java - Spring 启动 JPA : How do I connect multiple databases?

java - 错误由: java. lang.ClassNotFoundException : org. springframework.security.context.DelegatingApplicationListener引起

java - 表数据覆盖

java - 通过Java Stream实现多个集合的笛卡尔积

java - 合并集合图

java - 如何将 SQLServer "CAST(0xBB330B00 AS Date)"转换为 MySQL 语法

java - 在复制构造函数中复制监听器/观察器