gpt4 book ai didi

java - 区别对待?在扩展和 super

转载 作者:行者123 更新时间:2023-12-03 20:48:18 26 4
gpt4 key购买 nike

我希望可以使用任何类型来代替通配符 (?)。
扩展是真的(正如我所料),但它是 super 编译错误(我不明白为什么它与扩展示例不同)。
我应该如何看待这种差异 - 这是一个错误还是一个功能?

class Why {

void fSuper(List<? super Map<String,?>> lst) { }

void fExtends(List<? extends Map<String,?>> lst) { }

void test(){

// Why any type instead of ? gives error
fSuper(new ArrayList<Map<String, String>>()); // compile ERR - WHY ???
fSuper(new ArrayList<Map<String, Byte>>()); // c. ERR - WHY ???
fSuper(new ArrayList<Map<String, Map<Short, Boolean>>>()); // c. ERR - WHY ???
fSuper(new ArrayList<Map<String,?>>()); // OK

// Any type instead of ? can be used OK
fExtends(new ArrayList<Map<String, String>>()); // OK
fExtends(new ArrayList<Map<String, Byte>>()); // OK
fExtends(new ArrayList<Map<String, Map<Short, Boolean>>>()); // OK
fExtends(new ArrayList<Map<String,?>>()); // OK
这个问题的灵感来自 pdem here 的回答中的示例
他的例子似乎与我的 IDE 非常不一致
void populateList(List<? super Map<String,?>> list) {
list.clear();
Map<String, String> map;
map = new HashMap<String,String>();
map.put("key", "value"); // compiles
// Map<String, String> for List<? super Map<String,?>>
list.add(map); // compiles !!
}
附言我了解 PECS(生产者扩展/消费者 super )。 (请不要因为这个原因关闭问题)。但是我在我的第一个代码片段中没有看到如何使用它。我想我完全理解第二个代码片段。但我不明白为什么 ArrayList<Map<String, String>>不会在我的第一个代码片段中编译(使用 ...? super),但会在第二个代码片段中编译,并且会在我的第一个代码片段中编译(使用 ...? 扩展)。
我还意识到使用通配符 (?) 通常会带来麻烦(尤其是在违反 PECS 规定的情况下)。
但是 我想深入了解泛型,到目前为止,第一个代码片段击败了我的理解。

最佳答案

根据@Nathan Hughes 建议的帖子,我找到了 this excellent article .

A wildcard instantiation with a lower bound is supertype of all instantiations of the generic type where the type argument is a supertype of the lower bound.


在当前情况下,对于 List<? super <Map<String, ?>> , 我们只能分配类型参数为 Map<String, ?> 父类(super class)型的类型.
一般来说,对于下界通配符,我们应该能够反向分配类型参数,(即,在语句中,LHS 中的类型参数必须可以分配给 RHS 中的类型参数)。
在下面的代码中,我们不能将前 3 个值分配给类型参数。因此,具有此类型参数的子类型也不能分配给列表。
HashMap m = new HashMap();
Map<String, String> m1 = (Map<String, ?>)(m); //error
Map<String, Byte> m2 = (Map<String, ?>)(m); //error
Map<String, Map<Short, Boolean>> m3 = (Map<String, ?>)(m); //error
Map<String, ?> m4 = (Map<String, ?>)(m); // ok

关于java - 区别对待?在扩展和 super ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64486064/

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