gpt4 book ai didi

java - 泛型类型和通配符类型的区别

转载 作者:IT老高 更新时间:2023-10-28 20:35:25 27 4
gpt4 key购买 nike

我是 Generic 的新手,我的问题是:两个函数有什么区别:

功能1:

public static <E> void funct1  (List<E> list1) {

}

功能2:

public static void funct2(List<?> list) {

}

最佳答案

第一个签名说:list1 是一个 Es 列表。

第二个签名说:list 是某种类型的实例列表,但我们不知道类型。

当我们尝试更改方法时,差异变得明显,因此它需要第二个参数,该参数应添加到方法内的列表中:

import java.util.List;

public class Experiment {
public static <E> void funct1(final List<E> list1, final E something) {
list1.add(something);
}

public static void funct2(final List<?> list, final Object something) {
list.add(something); // does not compile
}
}

第一个效果很好。而且您不能将第二个参数更改为可以实际编译的任何内容。

实际上,我刚刚发现了一个更好的差异演示:

public class Experiment {
public static <E> void funct1(final List<E> list) {
list.add(list.get(0));
}

public static void funct2(final List<?> list) {
list.add(list.get(0)); // !!!!!!!!!!!!!! won't compile !!!!!!!!!
}
}

也许我们为什么需要<?>当它只限制我们可以用它做什么时(正如@Babu_Reddy_H 在评论中所做的那样)。我看到了通配符版本的以下好处:

  • 调用者必须对他传入的对象了解更少。例如,如果我有一个列表映射:Map<String, List<?>>我可以将其值传递给您的函数,而无需指定列表元素的类型。所以

  • 如果我分发像这样参数化的对象,我会主动限制人们对这些对象的了解以及他们可以用它做什么(只要他们远离不安全的转换)。

当我将它们结合起来时,这两个是有意义的:List<? extends T> .例如考虑一个方法 List<T> merge(List<? extends T>, List<? extends T>) ,它将两个输入列表合并到一个新的结果列表中。当然,您可以再引入两个类型参数,但您为什么要这样做呢?这将是过度指定的事情。

  • 最后,通配符可以有下限,因此使用列表可以使 add方法工作,而 get没有给你任何有用的东西。这当然会引发下一个问题:为什么泛型没有下界?

如需更深入的回答,请参阅:When to use generic methods and when to use wild-card?http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#FAQ203

关于java - 泛型类型和通配符类型的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10943137/

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