gpt4 book ai didi

java - 为什么这个简单的 Java 通用函数不能编译?

转载 作者:搜寻专家 更新时间:2023-10-31 08:10:30 24 4
gpt4 key购买 nike

虽然 f1 可以编译,但非常相似的 f2 不会,我无法解释原因。(在 Intellij 9 和 Eclipse 3.6 上测试)

我真的以为我已经完成了那种问题。

import java.util.*;
public class Demo {

public List<? extends Set<Integer>> f1(){
final List<HashSet<Integer>> list = null;
return list;
}

public List<List<? extends Set<Integer>>> f2(){
final List<List<HashSet<Integer>>> list = null;
return list;
}

}

最佳答案

List<List<HashSet<Integer>>>不可分配给 List<List<? extends Set<Integer>>>同理List<HashSet<Integer>>不能分配给 List<Set<Integer>> .

你可以通过改变这个让它编译:

public  List<List<? extends Set<Integer>>> f2(){

进入这个:

public  List<? extends List<? extends Set<Integer>>> f2(){

你的代码没有编译的原因,以及为什么我给出的另一个例子(即:“List<HashSet<Integer>> 不能分配给 List<Set<Integer>> ”)是 Java generics are not covariant .

典型的例子是即使Circle延伸Shape , List<Circle> 扩展List<Shape> .如果是,那么 List<Circle>需要有一个 add(Shape)接受 Square 的方法对象,但显然您不希望能够添加 Square反对 List<Circle> .

当您使用通配符时,您将获得一种切掉某些方法的类型。 List<? extends Shape>保留返回 E 的方法, 但它没有任何采用 E 的方法作为参数。这意味着您仍然拥有 E get(int)方法,但是 add(E)离开了。 List<? extends Shape>List<Shape> 的父类(super class)型以及List<Circle> , List<? extends Circle>等(? super 通配符以另一种方式切片:返回类型参数值的方法被删除)

你的例子更复杂,因为它有嵌套的类型参数,但它归结为同一件事:

  • List<HashSet<Integer>>List<? extends Set<Integer>> 的子类型
  • 因为泛型不是协变的,所以将两种类型包装在一个泛型类型中(如 List<...> )会产生一对不再具有子/父类(super class)型关系的类型。即 List<List<HashSet<Integer>>> 不是 List<List<? extends Set<Integer>>> 的子类型
  • 如果不用 List<...> 换行你用 List<? extends ...> 包装您最终会保留原始关系。 (这只是一个经验法则,但它可能涵盖了您想要使用通配符的 80% 的情况。)

请注意,trashgod 和 BalusC 都是正确的,因为您可能不希望返回这种奇怪的类型。 List<List<Set<Integer>>>将是更正常的返回类型。只要您始终坚持使用集合接口(interface)而不是具体的集合类作为类型参数,那应该可以正常工作。例如:你不能分配 List<ImmutableSet<Integer>>List<Set<Integer>> , 但你可以把 ImmutableSet<Integer>实例到 List<Set<Integer>> ,所以永远不要说 List<ImmutableSet<Integer>> ,说 List<Set<Integer>> .

关于java - 为什么这个简单的 Java 通用函数不能编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3644679/

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