1

I am trying to determine if it is possible to use Generics in the following situation. It can best be described by my code. (This code is just an example; I took out most of the code not relevant to the problem I'm having.)

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 { 

}

The compiler is saying that I can't call convertToModelList (in MyClient) because a Map<String, Class<? extends MyModel>> is not equivalent to Map<String, Class<T>>. I somewhat understand why this is occurring, but is there a way around this?

EDIT:

To be more specific, the problem I'd like to solve is using Generics in the convertToModelList() method above. If I can't use generics here, then whatever I return from that method has to be cast on the client. For example, if I change FooBar to this:

public class FooBar {

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

        // do stuff...
    }
}

If I pass in a

Map<String, Class<Truck>> 

to convertToModelList, it will return a

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

, however the client won't know it's a Truck - all it will know is that it's of type MyModel - using generics lets me avoid the cast to Truck in the MyClient code:

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);
}
}
acvcu
  • 2,476
  • 10
  • 40
  • 56
  • 1
    You need to clean up your example code a bit more. I'm not sure where constraint is supposed to be coming from in class myClient, since that class def is outside of FooBar, which does define a . A few other typos which I could guess at, but would rather not. – Kevin Welker Feb 15 '12 at 18:40
  • 1
    possible duplicate of [In Java is it possible to create a Map of classes to instances of their class?](http://stackoverflow.com/questions/6795025/in-java-is-it-possible-to-create-a-map-of-classes-to-instances-of-their-class) – Louis Wasserman Feb 15 '12 at 18:41
  • I've cleaned up the code a bit in the myClient class. – acvcu Feb 15 '12 at 18:54
  • @acvcu : Your myClient class still won't compile. – ARRG Feb 15 '12 at 18:58

2 Answers2

0

Since it extends MyModel, you are saying you only want that type.

It is valid to make it just MyModel and not ? extends MyModel.

Class<MyModel>

Then, any objects that extends this (which will be all the Car and Truck, will have to call the super method of MyModel. This will mean they are all of this type.

0

Although the common superclass of Car and Truck is MyModel, the common superclass of List<Car> and List<Truck> is Object. The map should be of type Map<Class<? extends MyModel>, Object>>. You better wrap the map with some invariant checks and casting instead of getting info directly from the map.

This may be helpful too: Heterogeneous container to store genericly typed objects in Java

Community
  • 1
  • 1
Bob Wang
  • 606
  • 4
  • 8
  • I don't need to use Map, Object>, because I know that the Object type is a List extends MyModel>. That means that the way I have it, as Map, List extends MyModel>> should work fine. – acvcu Feb 15 '12 at 22:01
  • `List extends MyModel>` is also a supertype of `List` and `List` – newacct Feb 16 '12 at 01:21