简体   繁体   English

通用通配符正确使用

[英]Generics Wildcards Proper Use

I have an object defined as follow: 我有一个定义如下的对象:

protected Map<String, ? extends List<? extends LightGeometry>> geoms=new HashMap<String,List<LightGeometry>>();

I try to insert in an object that looks conform to the wildcard 我尝试插入看起来符合通配符的对象

ArrayList<LightGeometry> points=new ArrayList<LightGeometry>();
points.add((LightGeometry)new LightPoint(pt));
geoms.put("point", points);

The compiler throws an error that says: 编译器将引发一个错误,指出:

The method put(String, capture#18-of ? extends List<? extends LightGeometry> ) in the type Map<String,capture#18-of ? extends List<? extends LightGeometry>> 类型为Map<String,capture#18-of ? extends List<? extends LightGeometry>>的方法put(String, capture#18-of ? extends List<? extends LightGeometry>Map<String,capture#18-of ? extends List<? extends LightGeometry>> Map<String,capture#18-of ? extends List<? extends LightGeometry>> Map<String,capture#18-of ? extends List<? extends LightGeometry>> is not applicable for the arguments (String, ArrayList<LightGeometry>) Map<String,capture#18-of ? extends List<? extends LightGeometry>>不适用于参数(String, ArrayList<LightGeometry>)

What am I missing? 我想念什么?

EDIT: Why I am using the wildcard with the generic types It basically comes down to being able to assign the list (which I get through a service) to a the geoms object which is in another class, without having to sift through the list to cast. 编辑:为什么我要使用具有通用类型的通配符基本上归结为能够将列表(我通过服务获得)分配给另一个类中的geoms对象,而不必在列表中进行筛选投。

public void onSuccess(Map<String, ArrayList<LightPolygon>> result) {
    // TODO Auto-generated method stub
    GWT.log("" + result.size());
    Log.debug("" + result.size());
    long startTime = System.currentTimeMillis();
    if (overlay != null) {
        overlay.setData(result);
        overlay.update();
        Log.debug("time to add features: "
                + (System.currentTimeMillis() - startTime));
    }
}

If I were to make the geoms variable a Map<String, List<LightGeometry>> then I get a cast error that says that I can't assign a Map<String,ArrayList<LightPolygon>> to a 'Map>` 如果我要使geoms变量成为Map<String, List<LightGeometry>>那么我会收到一个转换错误,说我无法将Map<String,ArrayList<LightPolygon>>分配给'Map>`。

A generic wildcard does not mean "Anything that extends List" It means "Some specific thing that extends List, but I don't know what that specific thing is." 通用通配符并不表示“扩展列表的任何内容”,而是表示“扩展列表的某些特定内容,但我不知道该特定内容是什么”。

Therefore it is illegal to add anything to the collection, because you don't know what the specific thing is! 因此,向集合中添加任何内容都是违法的,因为您不知道具体是什么! It could be a map of LinkedLists, and here you are putting an ArrayList in it, which would cause someone else to get class cast exception when they assume it's a LinkedList. 它可能是LinkedLists的映射,在这里您将ArrayList放入其中,这会导致其他人在假定它是LinkedList时获得类强制转换异常。

If you want a Map that holds any type of list, just declare it as a Map of Lists, not a Map of ? 如果您想要一个包含任何类型列表的Map,只需将其声明为List列表,而不是?的Map。 extends List. 扩展列表。

-- -

tl;dr - it does what you want without the wildcards. tl; dr-它无需通配符即可完成您想要的操作。 Wildcards are usually used for specifying method signatures where it doesn't matter if you know what the types are. 通配符通常用于指定方法签名,如果您知道类型是什么,则不要紧。 If you just want a collection that holds subclasses, you just specify the supertype. 如果只需要一个包含子类的集合,则只需指定超类型。

example: 例:

Map<String, List<Number>> map = new HashMap<String,List<Number>>();

List<Number> integers =new ArrayList<Number>();
integers.add(Integer.valueOf(1));
map.put("integers", integers);

List<Number> floats = new LinkedList<Number>(); 
floats.add(Float.valueOf(5.2f));
map.put("floats", floats);

No casting! 没有铸造!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM