gpt4 book ai didi

java - 为什么这个涉及通配符的赋值在 Java 中是合法的?

转载 作者:行者123 更新时间:2023-12-03 11:17:38 25 4
gpt4 key购买 nike

大多数关于通配符的问题都想知道为什么编译器会拒绝一些合理的东西。我的问题是相反的。为什么下面的程序会被编译器接受?

void test(List<? extends Number> g1, List<? extends Number> g2)
{
g1 = g2;
}
我试图从 Java 语言规范中解释这一点,但我还没有找到答案。我从 Java 泛型和通配符的各种描述中得到的印象是,通配符的每次使用都被捕获为一种全新的类型,但显然不是在这里。我还没有发现允许此分配后出现任何令人讨厌的行为,但它似乎仍然是“错误的”。

最佳答案

List<? extends Number>最好读成:
这是一个数字列表,但是,协变。
换句话说,这是一些具体但未知类型的列表。但是,我确实知道,无论它是什么类型,至少它是 Number 或其某个子类。
泛型很奇怪;一旦你选择了一些差异,你就会得到相应的限制。在集合的情况下,“协方差”带有“不添加”的包袱。
尝试一下。g1.add(XXX);唯一对 XXX 合法的事情这里? null .字面意思就是这样。您可以添加到此内容的所有内容的完整列表。当然Number x = 5; g1.add(x); javac 在这里是不允许的。
通过写作 List<? extends a thingie>你是说:是的,我想要那个。我签署了这个限制,我绝对不能添加任何内容(除了文字 null 的学术案例)。给自己戴上手铐的交易,你可以通过的东西g1得到了很大的扩展。
您还可以选择逆变:

void foo(List<? super Integer> list) {
list.add(Integer.valueOf(5)); // works!
Integer x = list.get(0); // no go
}
逆变则相反。添加作品。获取不起作用。在这种情况下,这意味着:表达式的类型 list.get(0)只是.. Object .

现在我们已经介绍了:
void test(List<? extends Number> g1, List<? extends Number> g2) {}
意思是“我的第一个参数是一个数字列表,但我选择使用协方差手铐”,“我的第二个参数是一个数字列表,但我也选择了这个数字的协方差手铐”,现在为什么 java 让你写 g1 = g2 . g2 保证是 X<Y> , 其中 X 是 List 的一些具体子类,而 Y 是 Number或其某些子类。
这是 100% 兼容的,类型方面的,具有“某种类型的列表,其类型参数是 Number 的某种协变形式”的概念。你唯一能做的事 List<? extends Number>是调用 List 的方法,其中签名中的任何 T 都对参数“禁用”,并由边界替换( Number) 返回类型。
这就是.. 正是 List<? extends Number>正在描述,所以它是兼容的。

关于java - 为什么这个涉及通配符的赋值在 Java 中是合法的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63947339/

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