Java - generics & wildcards and interface versus implementation

I have a question about Java generics. Let's say I have the following interface:

public static class Something<T> { public void set(T t) { } } public static interface Manager<T> { public void add(final String key, final Something<T> o); public Something<T> get(final String key); } 

Usage example:

 final Manager<Number> m = ...; m.add("key", new Something<Number>()); m.get("key").set(new Integer(5)); 

I would also like to add Something<Integer> , Something<Double> , ... to Manager<Number> . I would say that I need to change the add-function signature:

 public static interface Manager<T> { public void add(final String key, final Something<? extends T> o); public Something<T> get(final String key); } final Manager<Number> m = ...; m.add("key", new Something<Integer>()); m.get("key").set(new Integer(5)); 

So far so good. Let's look at a possible implementation of a manager:

 public static class ManagerImplementation<T> implements Manager<T> { protected HashMap<String, Something<T>> map = new HashMap<String, Something<T>>(); public void add(final String key, final Something<? extends T> o) { map.put(key, o); // <--- here } public Something<T> get(final String key) { return map.get(key); } } 

This fails, since you cannot add Something<? extends T> Something<? extends T> to Map<X, Something<T>> . So let's change this:

 public static class ManagerImplementation<T> implements Manager<T> { protected HashMap<String, Something<? extends T>> map = new HashMap<String, Something<? extends T>>(); public void add(final String key, final Something<? extends T> o) { map.put(key, o); } public Something<T> get(final String key) { return map.get(key); // <--- here } } 

This is not so, since map.get(key) returns Something<? extends T> Something<? extends T> , while the get function is required to return Something<T> , as defined in the interface.

What is the general approach to solving this issue?

Thanks!

+6
source share
1 answer

Inside your class, you always use Something<? extends T> Something<? extends T> , so in your public get method, you must convert the inner world to the outer world format. For instance. you can simply pass the result of map.get(key) to Something<T> :

 return (Something<T>) map.get(key); // <--- here 
+3
source

Source: https://habr.com/ru/post/955475/


All Articles