pat*_*rit 3 java generics inheritance types
下面的代码编译,但如果我取消注释注释行,它不会,我很困惑为什么.HashMap确实扩展了AbstractMap,并且声明map的第一行编译正常.
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String args[]) {
Map<String, ? extends AbstractMap<String, String>> map = new HashMap<String, HashMap<String, String>>();
//map.put("one", new HashMap<String, String>());
}
}
Run Code Online (Sandbox Code Playgroud)
而且,我知道"正确的方法"是这样的:
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String args[]) {
Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
map.put("one", new HashMap<String, String>());
}
}
Run Code Online (Sandbox Code Playgroud)
第一个代码是不安全的 - 假设你真的写了:
HashMap<String, ConcurrentHashMap<String, String>> strongMap =
new HashMap<String, ConcurrentHashMap<String, String>>();
Map<String, ? extends AbstractMap<String, String>> map = strongMap;
Run Code Online (Sandbox Code Playgroud)
现在:
map.put("one", new HashMap<String, String>());
ConcurrentHashMap<String, String> x = strongMap.get("one");
Run Code Online (Sandbox Code Playgroud)
我们应该有ConcurrentHashMap- 但实际上我们只有一个HashMap.
如果我们减少正在进行的泛型数量,这实际上要简单得多解释......你的场景实际上相当于(比如说):
List<? extends Fruit> list = new List<Apple>();
list.add(new Apple());
Run Code Online (Sandbox Code Playgroud)
看起来没问题,直到你认为它的有效性(就编译器而言)相当于:
List<Apple> apples = new ArrayList<Apple>();
List<? extends Fruit> list = apples;
list.add(new Orange());
Apple apple = list.get(0); // Should be okay... but element 0 is an Orange!
Run Code Online (Sandbox Code Playgroud)
这显然是不正常.编译器必须以相同的方式处理这两个,因此它们都使它们无效.
| 归档时间: |
|
| 查看次数: |
378 次 |
| 最近记录: |