Eli*_*her 2 java generics object
public interface A {
int getA();
}
public class MyObj implements A {
public int getA(){
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
如果有地图: Map<? extends A, String> aMap = new HashMap<>();
我如何可以将添加MyObj到这个aMap?或者该如何成为该类MyObj以便它可以在此映射中工作
我如何可以将添加
MyObj到这个aMap?
你不能,因为键类型的上限.
原因? extends A可能是MyOtherObj implements A.在这种情况下,能够将类型的键MyObj放入地图是不安全的:
Map<MyOtherObj, String> anotherMap = new HashMap<>();
Map<? extends A, String> aMap = anotherMap;
aMap.put(new MyObj(), ""); // Can't do this; but if you could...
MyOtherObj obj = anotherMap.keySet().iterator().next(); // ClassCastException!
Run Code Online (Sandbox Code Playgroud)
记住首字母缩略词PECS(更多细节请参阅此问题):
extendssuper换句话说,Map<? extends A, String>只能用于生成实例A,它不能使用/接受实例A.
例如,您可以迭代键("生成"键):
for (A a : aMap.keySet()) { ... }
Run Code Online (Sandbox Code Playgroud)
地图只能"消耗"文字null:
aMap.put(null, "");
Run Code Online (Sandbox Code Playgroud)
因为null可以毫无例外地转换为任何类型.但是在只有一个键的地图中没有太多用处 - 您也可以直接存储该值.
安全地执行此类型操作的唯一方法是MyObj通过您知道接受MyObj实例的引用将实例放入地图:
Map<MyObj, String> safeMap = new HashMap<>();
safeMap.put(new MyObj(), "");
Map<? extends A, String> aMap = safeMap;
Run Code Online (Sandbox Code Playgroud)
要么
Map<A, String> safeMap = new HashMap<>();
safeMap.put(new MyObj(), "");
Map<? extends A, String> aMap = safeMap;
Run Code Online (Sandbox Code Playgroud)
但你应该考虑根本没有通配符类型的地图; Map<MyObj, String>或者Map<A, String>更容易.