gpt4 book ai didi

Java 泛型方法,通配符 List 返回类型

转载 作者:行者123 更新时间:2023-11-30 06:52:08 31 4
gpt4 key购买 nike

Java 的 8 方法签名如下所示:

public static <E extends CharSequence> List<? super E> m(List<E> list);

在代码的某处,方法调用:

result = m(list);

假设我创建了参数 list如下:

List<String> list = new ArrayList<>();

我的问题是,为什么 result可以只是原始的 List , 甚至不能是 List<Object>

最佳答案

使用 List<String> 调用您的方法作为参数就像调用以下方法:

public static List<? super String> m(List<String> list) { ... }

考虑以下起始代码:

List<String> list = new ArrayList<>();
List<? super String> result = m(list);

这将调用上述方法并将返回值存储到变量 result 中- 与方法的返回类型完全相同。

现在的问题是:您可以将这个变量分配给什么变量——或者更好的是什么类型?所以我们谈论的是分配兼容性。

考虑这些分配:

List<String> result1 = result; // compiler error: type mismatch (not assignable)
List<Object> result2 = result; // compiler error: type mismatch (not assignable)

List result3 = result; // ok
List<?> result4 = result; // ok

List<? super String> result5 = result; // ok
List<? extends Object> result6 = result; // ok

要了解此错误的性质,您必须知道泛型是不变的。这意味着,类型 List<String> 不是 List<Object> 的子类型- 虽然类型 StringObject有这样的子类型层次结构。

所以,我们在这里尝试的是:

  1. 分配 List<? super String>List<String> => 失败,没有子类型
  2. 分配 List<? super String>List<Object> => 失败,没有子类型
  3. 分配 List<? super String>List => 成功,因为使用原始类型通常会退出类型检查
  4. 分配 List<? super String>List<?> => 成功,因为 List<?>是所有 List<...> 的父类(super class)型
  5. 分配 List<? super String>List<? super String> => 成功了,因为……好吧……
  6. 分配 List<? super String>List<? ectends Object> => 成功,因为 List<? ectends Object>本质上与 List<?> 相同.

请注意,尝试分配 List<? super String>List<? super CharSequence>List<? extends CharSequence>也会失败。它们不在子类型层次结构中。

为什么会这样?编译器不能保证实际列表是用与约束 ? super/extends CharSequence 匹配的类型实例化的。 .

关于Java 泛型方法,通配符 List 返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39488046/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com