The problem: I've a Function Object interface defined in a class:
public static interface FunctionObject<T> {
void process(T object);
}
I need it generic because I'd like to use T methods in the process implementations.
Then, in other generic class, I've a Map where I have classes as keys and function objects as values:
Map<Class<T>, FunctionObject<T>> map;
But I also want the map to accept subtype classes and function objects of supertypes OF THE KEY TYPE, so I did this:
Map<Class<? extends T>, FunctionObject<? super T>> map; //not what I need
The basic idea is to be able to use the map as follows:
//if T were Number, this should be legal
map.put(Class<Integer>, new FunctionObject<Integer>(){...});
map.put(Class<Float>, new FunctionObject<Number>(){...});
map.put(Class<Double>, new FunctionObject<Object>(){...});
As I want to enforce the FunctionObject has the type of the class key or a supertype, what I really would like to define is this:
Map<Class<E extends T>, FunctionObject<? super E>>> map;
How can I achieve the desired effect? Is a typesafe heterogenous container the only option? What would the Map generic types look like to allow populating it from a reference?
Parametrized container, seems to work just fine:
public class MyMap<T>
{
interface FunctionObject<X> {}
private Map<Class<? extends T>, FunctionObject<Object>> map = new HashMap<>();
@SuppressWarnings("unchecked")
public <E extends T> void put(Class<E> c, FunctionObject<? super E> f)
{
map.put(c, (FunctionObject<Object>) f);
}
public <E extends T> FunctionObject<Object> get(Class<E> c)
{
return map.get(c);
}
public static void Main(String[] args)
{
MyMap<Number> map = new MyMap<>();
map.put(Integer.class, new FunctionObject<Integer>() {});
map.put(Float.class, new FunctionObject<Number>() {});
map.put(Double.class, new FunctionObject<Object>() {});
}
}
Edited to comply to the question. Sadly there is no way to avoid the downcasting to object.
Edit added get().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With