在泛型中使用方法中的Map

时间:2012-02-15 18:12:08

标签: java generics

我正在尝试确定在以下情况下是否可以使用Generics。最好用我的代码来描述。 (这段代码只是一个例子;我拿出了大部分与我遇到的问题无关的代码。)

public class FooBar {

    public <T extends MyModel> Map<Class<T>, List<T>> convertToModelList(
            Map<String, Class<T>> infoMap) {

        // do stuff...
    }
}

public class MyClient {

public void doSomething() {
    Map<String, Class<? extends MyModel>> oldMap = new HashMap<String, Class<? extends MyModel>>();
    oldMap.put ("car", Car.class);
    oldMap.put("truck", Truck.class);

    FooBar f = new FooBar();
    Map<Class<? extends MyModel>, List<? extends MyModel>> newMap = f
            .convertToModelList(oldMap);
}
}

public class Car extends MyModel {

}

public class Truck extends MyModel {

}

public class MyModel { 

}

编译器说我无法调用convertToModelList(在MyClient中),因为Map<String, Class<? extends MyModel>>不等同于Map<String, Class<T>>。我有点理解为什么会这样,但有没有办法解决这个问题呢?

编辑:

更具体地说,我想解决的问题是在上面的convertToModelList()方法中使用Generics。如果我不能在这里使用泛型,那么无论我从该方法返回什么都必须在客户端上进行。例如,如果我将FooBar更改为:

public class FooBar {

    public Map<Class<? extends MyModel>, List<? extends MyModel>> convertToModelList(
            Map<String, Class<? extends MyModel>> infoMap) {

        // do stuff...
    }
}

如果我传入

Map<String, Class<Truck>> 

到convertToModelList,它将返回一个

Map<Class<Truck>, List<Truck>>

,但是客户端不会知道它是卡车 - 它只会知道它是MyModel类型 - 使用泛型让我避免在MyClient代码中转换为Truck:

public class MyClient {

public void doSomething() {
    Map<String, Class<? extends MyModel>> oldMap = new HashMap<String, Class<? extends MyModel>>();
    oldMap.put ("car", Car.class);
    oldMap.put("truck", Truck.class);

    FooBar f = new FooBar();
    Map<Class<? extends MyModel>, List<? extends MyModel>> newMap = f
            .convertToModelList(oldMap);

            // I'm trying to avoid this cast
            List<Truck> trucks = (List<Truck>)newMap.get(Truck.class);
}
}

2 个答案:

答案 0 :(得分:0)

由于它扩展了MyModel,你说你只想要那种类型。

将其设为MyModel是否有效?扩展MyModel。

Class<MyModel>

然后,任何扩展它的对象(将是所有Car和Truck,都必须调用MyModel的超级方法。这意味着它们都是这种类型。

答案 1 :(得分:0)

虽然CarTruck的常见超类是MyModel,但List<Car>List<Truck>的常见超类是Object。地图应为Map<Class<? extends MyModel>, Object>>类型。你最好用一些不变的检查和转换来包装地图,而不是直接从地图上获取信息。

这也可能有用:Heterogeneous container to store genericly typed objects in Java