列表<?超级列表<?超级整数>>和列表<?扩展列表 <? super Integer>> 以及如何正确使用它?
List<? super List<? super Integer>> and List<? extends List<? super Integer>> and how to use it correctly?
考虑以下片段:
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必须是这样的,list的所有元素都会满足条件
? super List<? super Integer>
- 但是
doubleList
/ integerList
/ numberList
无论如何都不满足这个条件——因为我们期望一个类型是 List<? super Integer>
.[=43= 的超类型]
- 为什么我们这里没有出现编译错误?
- 表达式:2
- 这里我们期望RHS上的元素一定是
subtype of List<? super Integer>
- 所以
doubleList
直观上可以看做是满足条件的候选
- 如果我在
Arrays.asList
表达式中包含 doubleList
,为什么仍然出现编译错误?.
不确定我是否以正确的方式解释这些表达式 - 可能有什么问题,从逻辑上讲它似乎不符合我上面给出的解释?
编译的两种情况,编译是因为类型推断算法会尽力推断 asList
调用的类型参数以使您的代码编译。这与三个列表的类型无关(它们只是间接相关)。都是关于 Arrays.asList
returns.
的类型
第一种情况:
List<? super List<? super Integer>> superDoubleList = Arrays.asList(doubleList, integerList,numberList);
要编译您的代码,Arrays.asList
,只需创建一个 List<List<?>>
。毕竟三个列表都是“something的列表”,所以这是可以的。
而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
、integerList
和 numberList
的列表可以做到这一点吗?当然,不管列表的内容是什么,您总是可以向列表中添加另一个 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 的语法表达。
考虑以下片段:
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必须是这样的,list的所有元素都会满足条件
? super List<? super Integer>
- 但是
doubleList
/integerList
/numberList
无论如何都不满足这个条件——因为我们期望一个类型是List<? super Integer>
.[=43= 的超类型] - 为什么我们这里没有出现编译错误?
- 这里我们说RHS上的List必须是这样的,list的所有元素都会满足条件
- 表达式:2
- 这里我们期望RHS上的元素一定是
subtype of List<? super Integer>
- 所以
doubleList
直观上可以看做是满足条件的候选 - 如果我在
Arrays.asList
表达式中包含doubleList
,为什么仍然出现编译错误?.
- 这里我们期望RHS上的元素一定是
- 表达式:1
不确定我是否以正确的方式解释这些表达式 - 可能有什么问题,从逻辑上讲它似乎不符合我上面给出的解释?
编译的两种情况,编译是因为类型推断算法会尽力推断 asList
调用的类型参数以使您的代码编译。这与三个列表的类型无关(它们只是间接相关)。都是关于 Arrays.asList
returns.
第一种情况:
List<? super List<? super Integer>> superDoubleList = Arrays.asList(doubleList, integerList,numberList);
要编译您的代码,Arrays.asList
,只需创建一个 List<List<?>>
。毕竟三个列表都是“something的列表”,所以这是可以的。
而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
、integerList
和 numberList
的列表可以做到这一点吗?当然,不管列表的内容是什么,您总是可以向列表中添加另一个 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 的语法表达。