1

考虑以下代码段:

List<Double> doubleList = null;
List<Integer> integerList = null;
List<Number> numberList = null;

//expression:1
List<? super List<? super Integer>> superDoubleList = Arrays.asList(doubleList, integerList,numberList);

//expression:2
//here doubleList will cause compilation error
List<? extends List<? super Integer>> extendsDoubleList = Arrays.asList(integerList,numberList);//doubleList
  • 在这里,我试图了解如何解释这两个陈述
    • 表达式:1
      • 这里我们说 RHS 上的 List 必须使得列表的所有元素都满足条件? super List<? super Integer>
      • 但是doubleList//无论如何都不满足这个条件integerList-numberList因为我们期望一个类型是List<? super Integer>.
      • 仍然为什么我们在这里没有得到编译错误?
    • 表达:2
      • 在这里,我们期望 RHS 上的元素必须是subtype of List<? super Integer>
      • 所以doubleList直观上可以看成是一个能满足条件的候选。
      • 如果我包含doubleListArrays.asList表达式中,为什么仍然会出现编译错误?.

不确定我是否以正确的方式解释表达式 - 从逻辑上讲它似乎不符合我上面给出的解释可能有什么问题?

4

1 回答 1

4

编译的两种情况都可以编译,因为类型推断算法会尽力推断asList调用的类型参数以使您的代码编译。这与三个列表的类型无关(它们只是间接相关)。这都是关于Arrays.asList返回的类型。

在第一种情况下:

List<? super List<? super Integer>> superDoubleList = Arrays.asList(doubleList, integerList,numberList);

要使您的代码编译,Arrays.asList只需创建一个List<List<?>>. 毕竟,这三个列表都是“某物的列表”,所以这是可能的。

并且List<List<?>>是一种List<? super List<? super Integer>>。这是因为List<?>它是一种超类型List<? super Integer>——“一些Integer超类型的列表”是一种“一些对象的列表”。

对此的另一种解释是,将其? super T视为“消费者T”和? extends T“生产者T”。(PECS)在这种解释中,List<? super List<? super Integer>>意思是“一个可以使用可以使用整数的列表列表。列表上下文中的“使用”仅表示“添加”。可以包含doubleList,的列表integerListnumberList做到这一点吗?当然,列表的内容是什么并不重要,您总是可以将另一个添加List<? super Integer>到列表中。只是列表的类型必须是List<List<?>>. 即使这样也有效:

List<? super List<? super Integer>> superDoubleList =
    Arrays.asList(new ArrayList<String>(), new ArrayList<LocalDate>());

使用相同的解释,List<? extends List<? super Integer>>表示“可以生成使用整数的列表的列表” 。能

Arrays.asList(integerList,numberList)

去做?是的,这两个内部列表都可以使用整数,因此外部列表可以“生成使用整数的列表”,或者换句话说,是此类列表的生产者

这个列表列表呢?

Arrays.asList(doubleList,integerList,numberList)

它是可以消费整数的列表的生产者吗?嗯,不,因为doubleList不消耗整数,但它可以产生。

您可能想知道 Java 编译器asList在这种情况下推断出的类型是什么:

List<? extends List<? super Integer>> extendsDoubleList = Arrays.asList(integerList,numberList);

asList可以创建一个List<List<? super Integer>>. 然而,实际推断的类型似乎是别的东西,不能用 Java 的语法来表达。

于 2021-10-30T12:11:31.133 回答