Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a generic typesafe HashMap by class type? [duplicate]

Tags:

java

generics

I'd like to create a HashMap that maps specific class types to one single specific new object.

Later I want to pass the class type and get the reference to that specific object. Simple example:

Map<Class<?>, ?> values = new HashMap<>();

public <T> t get(Class<T> type) {
    return values.get(type);
}


//pet and car do not share any interface or parent class
class Pet;
class Car;

//error: not applicable for arguments
values.put(Pet.class, new Pet());
values.put(Car.class, new Car());

usage:

values.get(Pet.class);

How can I create such a generic hashmap and lookup function accordingly?

like image 327
membersound Avatar asked Apr 08 '14 15:04

membersound


1 Answers

You need to store some type of object, if you want to be able to put anything else as Object in the map, so start off with this:

Map<Class<?>, Object> values = new HashMap<>();

This has to be done this way, because ? is not a concrete object, but Object is, for the type the map stores.

So the following snippet works, without warnings:

Map<Class<?>, Object> values = new HashMap<>();
values.put(Pet.class, new Pet());
values.put(Car.class, new Car());

Now the trick is to get objects, we do it as follows:

@SuppressWarnings("unchecked")
private <T> T get(Class<T> clazz) {
    return (T)values.get(clazz);
}

Now your goal is to ensure that the map contains pairs that provide no errors on runtime. If you put a new Car() instance with Car.class , then you are going to get errors.

So the following example code:

    values = new HashMap<>();
    values.put(Pet.class, new Pet());
    values.put(Car.class, new Car());

    System.out.println("get(Pet.class).getClass() = " + get(Pet.class).getClass());
    System.out.println("get(Car.class).getClass() = " + get(Car.class).getClass());

will print:

get(Pet.class).getClass() = class testproject8.Pet
get(Car.class).getClass() = class testproject8.Car
like image 116
skiwi Avatar answered Oct 03 '22 19:10

skiwi