我正在尝试确定在以下情况下是否可以使用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);
}
}
答案 0 :(得分:0)
由于它扩展了MyModel,你说你只想要那种类型。
将其设为MyModel是否有效?扩展MyModel。
Class<MyModel>
然后,任何扩展它的对象(将是所有Car和Truck,都必须调用MyModel的超级方法。这意味着它们都是这种类型。
答案 1 :(得分:0)
虽然Car
和Truck
的常见超类是MyModel
,但List<Car>
和List<Truck>
的常见超类是Object
。地图应为Map<Class<? extends MyModel>, Object>>
类型。你最好用一些不变的检查和转换来包装地图,而不是直接从地图上获取信息。
这也可能有用:Heterogeneous container to store genericly typed objects in Java