n247s n247s - 6 months ago 28
Java Question

Generics wildcard isnt capable to cast to Generictype

I came across a problem I wasn't able to find a solution for.

I often make use of a mapping where the key and value are objects with matching generictypes. For each pair the generics should match. Though the generictypes between entries may varry. (Ill include an example for clarity).
This can easily be accomplished with the use of the wildCard. although because of this, you cannot use the key or value in combination with eachother.

Consider the example included at the bottom. there is no (easy) way to modify the map to run into Cast exceptions. Though I still won't be able to use the map like I tried within

useEntries()
. So my question is, is there a workaround for this? Thanks in advance!

public class GenericWildcardTest
{
static Map<GenericObject<?>, Function<?, ?>> map = new HashMap<>();

public static <S> void put(GenericObject<S> genericObject, Function<S, S> function)
{
map.put(genericObject, function);
}

public static void useEntries()
{
for(Entry<GenericObject<?>, Function<?, ?>> currentEntry : map.entrySet())
//The #apply(); part simply wont compile because of cast errors.
currentEntry.getKey().set(currentEntry.getValue().apply(currentEntry.getKey().get()));
}



// Simple Object with generic.
static class GenericObject<T>
{
private T object;

public GenericObject(T object)
{
this.object = object;
}

public void set(T object)
{
this.object = object;
}

public T get()
{
return this.object;
}
}
}

Answer

You can rewrite the useEntries method as follows:

@SuppressWarnings("unchecked")
public static void useEntries() {
    for (Map.Entry<GenericObject<?>, Function<?, ?>> currentEntry : map.entrySet()) {
        GenericObject key = currentEntry.getKey();
        Function value = currentEntry.getValue();
        key.set(value.apply(key.get()));
    }
}

Removing the generics from the GenericObject and Function within the method will allow you to make the calls on pure Object instances. It's then your responsibility to assure correct typing. The annotation SuppressWarning will remove compilation warnings which would be printed otherwise.

Comments