gpt4 book ai didi

java - 为什么泛型父类(super class)型的 Java 类型推断会在这里中断?

转载 作者:行者123 更新时间:2023-12-04 14:37:43 25 4
gpt4 key购买 nike

鉴于此 Java 代码:

import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;

public class Test {
public static void main(String[] args) {
SimpleEntry<Integer, String> simpleEntry = new SimpleEntry<>(1, "1");
Optional<Entry<Integer, String>> optionalEntry = Optional.of(simpleEntry);
Optional<SimpleEntry<Integer, String>> optionalSimpleEntry = Optional.of(simpleEntry);

List<Entry<Integer, String>> list1 = Arrays.asList(simpleEntry);
List<Optional<Entry<Integer, String>>> list2 = Arrays.asList(optionalEntry);
List<Optional<SimpleEntry<Integer, String>>> list3 = Arrays.asList(optionalSimpleEntry);
List<Optional<Entry<Integer, String>>> list4 = Arrays.asList(optionalSimpleEntry);
}
}

表达式初始化 list , list2list3工作正常。但是,表达式初始化 list4在 Eclipse 中出现此错误:
Type mismatch: cannot convert from List<Optional<AbstractMap.SimpleEntry<Integer,String>>>
to List<Optional<Map.Entry<Integer,String>>>

和这个错误 javac :
Test.java:16: error: incompatible types: inference variable T has incompatible bounds
List<Optional<Entry<Integer, String>>> list4 = Arrays.asList(optionalSimpleEntry);
^
equality constraints: Optional<Entry<Integer,String>>
lower bounds: Optional<SimpleEntry<Integer,String>>
where T is a type-variable:
T extends Object declared in method <T>asList(T...)

但是 AbstractMap.SimpleEntry直接实现 Map.Entry .那么为什么类型推断会中断 list4当它适用于 list1list3 (以及分配给 optionalEntry ,就此而言)?

特别是我不明白为什么分配给 list1当分配给 list4 时有效才不是。

最佳答案

我想你明白为什么 Optional<SimpleEntry<Integer,String>>不能分配给 List<Optional<Entry<Integer, String>>> 类型的变量.如果没有,请阅读问答Is List a subclass of List? Why are Java generics not implicitly polymorphic?

但是,您的问题为什么list1声明有效,但 list4宣言。
list1之间有区别和 list4声明。对于 list1 ,形式为:

SimpleEntry<Integer, String> simpleEntry = ...;
List<Entry<Integer, String>> list = Arrays.asList<T>(simpleEntry);

在这种情况下,类型变量 TArrays.asList方法尚未固定到特定类型。它的上限为 SimpleEntry<Integer, String> ( simpleEntry 的类型)。

根据 Java Language Specification, section 18.5.2, "Invocation Type Inference" ,编译器会进一步约束类型 T通过约束 asList 的返回类型( List<T> ) 到调用上下文目标类型 ( List<Entry<Integer, String>> )。

这个有可能;当编译器选择 T 为 Entry<Integer, String> ,整个表达式都适合,因为类型为 SimpleEntry<Integer, String> 的值可以分配给 Entry<Integer, String> 类型的变量.

对于 list4 ,形式为:
SimpleEntry<Integer, String> simpleEntry = new SimpleEntry<>(1, "1");
Optional<SimpleEntry<Integer, String>> optionalSimpleEntry = Optional.of(simpleEntry);
List<Optional<Entry<Integer, String>>> list4 = Arrays.asList<T>(optionalSimpleEntry);

在这里, T最初被限制为 Optional<SimpleEntry<Integer, String>> 的上限.表达式上下文的目标类型是 List<Optional<Entry<Integer, String>>> .编译器不可能想出 T两者都适合。

类型为 Optional<SimpleEntry<Integer, String>> 的值不能分配给 Optional<Entry<Integer, String>>> 类型的变量.

这就是编译器提示的原因。

简单来说

简单来说,对于泛型类型不受约束且存在约束泛型类型的表达式上下文的方法,它适用于一层深度的参数化。

你可以说
Dog dog = ...;
List<Animal> animals = Arrays.asList(dog);

但它不适用于更深层次的参数化。
Optional<Dog> optionalDog = ...;
List<Optional<Animal>> optionalAnimals = Arrays.asList(optionalDog);

关于java - 为什么泛型父类(super class)型的 Java 类型推断会在这里中断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58945417/

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