两者之间有什么区别吗?
List<Map<String, String>>
和
List<? extends Map<String, String>>
如果没有区别,使用? extends
的好处是什么?
发布于 2012-03-22 02:18:45
不同之处在于,例如,
List<HashMap<String,String>>
是一个
List<? extends Map<String,String>>
但不是
List<Map<String,String>>
所以:
void withWilds( List<? extends Map<String,String>> foo ){}
void noWilds( List<Map<String,String>> foo ){}
void main( String[] args ){
List<HashMap<String,String>> myMap;
withWilds( myMap ); // Works
noWilds( myMap ); // Compiler error
}
您可能认为a List
of HashMap
s应该是a List
of Map
s,但有一个很好的理由证明它不是:
假设你可以这样做:
List<HashMap<String,String>> hashMaps = new ArrayList<HashMap<String,String>>();
List<Map<String,String>> maps = hashMaps; // Won't compile,
// but imagine that it could
Map<String,String> aMap = Collections.singletonMap("foo","bar"); // Not a HashMap
maps.add( aMap ); // Perfectly legal (adding a Map to a List of Maps)
// But maps and hashMaps are the same object, so this should be the same as
hashMaps.add( aMap ); // Should be illegal (aMap is not a HashMap)
这就是为什么a List
of HashMap
s不应该是List
of Map
s的原因。
发布于 2012-03-22 23:32:41
今天,我已经使用了这个功能,所以这是我非常新鲜的现实生活中的例子。(我已经将类和方法名称更改为泛型名称,这样它们就不会分散对实际问题的注意力。)
我有一个方法,用于接受我最初使用此签名编写的A
对象的Set
:
void myMethod(Set<A> set)
但它实际上想用A
的子类的Set
来调用它。但这是不允许的!(这样做的原因是,myMethod
可以向set
添加类型为A
的对象,但不是set
的对象在调用方站点声明的子类型。因此,如果可能的话,这可能会破坏类型系统。)
现在来看一下泛型,因为如果我使用这个方法签名,它就能正常工作:
<T extends A> void myMethod(Set<T> set)
或者更短一些,如果你不需要在方法体中使用实际的类型:
void myMethod(Set<? extends A> set)
这样,set
的类型就变成了A
的实际子类型的对象集合,因此可以在子类中使用它,而不会危及类型系统。
https://stackoverflow.com/questions/9810445
复制相似问题