Java generics: Declare map value of generic type
Asked Answered
P

4

6

I am new to generics.

Having a Map like

private static Map<String, Object> map;

and a method like

public <T> T getObject(final Class<T> myClass) {
    return (T)map.get(myClass);
}

How to change the map declaration in order to not have to do the cast when returning from the method ?

Pebrook answered 13/6, 2012 at 10:30 Comment(4)
Is there a chance for you to declare the map like Map<String, Class<T>>?Satiate
@Satiate The IDE is saying: T cannot be resolved to a typePebrook
I think @Pablo has a nice answer to this.Satiate
why do you have a non-static member function for a static field?Intrigue
E
10

You would need to make a generic class, not a generic method:

public class MyClass<T> {
   private Map<String, T> map;

   public T getObject(final String key) {
    return map.get(key);
   }
}

Also, I changed the parameter from a Class to a String. It doesn't make sense to pass a Class if map.get() expects a String.

Edit: I didn't notice that map was static. If you can change it to non-static without it breaking other parts of your program, this could work. If you can't, then you cannot avoid a cast.

Electrostriction answered 13/6, 2012 at 10:35 Comment(2)
Cannot make a static reference to the non-static type TPebrook
@DisplayName OK, map is static, I missed that. Then if you cannot change map from static to non-static, this won't work.Electrostriction
A
0

You can't avoid the cast operation as the get() method returns Object see here for more info

Amnesia answered 13/6, 2012 at 10:32 Comment(7)
Unless you can somehow declare the Map as being of type Map<String,T>, which doesn't seem to fit your exampleDamocles
@Damocles even so it wouldn't change the problem, the method get() returns an object, not an instance of TAmnesia
@Damocles I tried that, but does not work. Could you please tell me why ?Pebrook
@DisplayName it depends on how you did it. Maybe you can post the code? For one thing, the Map would have to be declared inside your class (the one that has the getObject) or you'll have two unrelated T's with different values.Damocles
Oh, there look at @Electrostriction that's howDamocles
@Amnesia Map.get() returns an object of type V, i.e. the generic type of its values (unsurprisingly) - javadocs. You might be thinking of the fact that the parameter to get is always an Object rather than a K?Shan
@AndrzejDoyle yes, I see the difference. Apparently the method signature changed over the Java releases and I didn't noticed so far. For example in 1.4, it used to return Object, hence my mistakeAmnesia
W
0

If you're willing to drop the static modifier of your map, than you can do like so:

public class MyClass<T> {

    private Map<String, T> map;

    public T getObject(final Class<T> myClass) {
        return map.get(myClass);
    }
}

Otherwise:

It is a compile-time error to refer to a type parameter of a generic class C anywhere in:

  • the declaration of a static member of C

(excerpt from the JLS), which prevents you from using parameterized class to achieve the above.

What you were trying to do, however, is to refer a parameterized method's type-parameter from another member (which happen to also be static), which also unreachable.

Whitehot answered 13/6, 2012 at 10:45 Comment(0)
R
0

my working generic java map

public class JsonUtils {
    /** gson with disable html escaping */
    public static Gson gson = new GsonBuilder().disableHtmlEscaping().create();

    public static <K, V> String toJson(Map<K, V> dataMap) {
        return gson.toJson(dataMap);
    }
}

usage

java.util.Map<String, Object> dataMap = new java.util.HashMap<>();
dataMap.put("paymentchannel", "BALANCE");
dataMap.put("shortcode", "");
dataMap.put("transtype", "cvm");
System.out.println(JsonUtils.toJson(dataMap));
Reverential answered 25/2 at 6:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.