I have two generic classes A<T>
and B<T>
and a list map entries of the type (A<T>, B<T>)
. However, the generic type T can be different between entries, but is the same in key-value pairs. I want a way ensure that a key of type A<T>
can only insert a value of type B<T>
and not some other generic class, and similarly, ensure that any value retrieved from key A<T>
is of type B<T>
.
CodePudding user response:
It's not possible to declare the Map with those constraints, but you can use unsafe casting privately and expose generic methods for public access:
private Map<A<?>, B<?>> map = new HashMap<>();
public <T> void put(A<T> key, B<T> value) {
map.put(key, value);
}
public <T> B<T> get(A<T> key) {
return (A<T>)map.get(key);
}
CodePudding user response:
Same solution as shmodel, but complete example:
class A<T> {
}
class B<T> {
}
class ABMap {
private final Map<A, B> map = new HashMap<>();
public <T> void put(A<T> key, B<T> value) {
map.put(key, value);
}
public <T> B<T> get(A<T> key) {
return map.get(key);
}
}
public class Test {
public static void main(String[] args) {
A<String> aString = new A<>();
B<String> bString = new B<>();
A<Integer> aInt = new A<>();
B<Integer> bInt = new B<>();
ABMap map = new ABMap();
map.put(aString, bInt); // compile error
map.put(aString, bString); // OK
B<String> b = map.get(aInt); // compile error
b = map.get(aString); // must be the correct type because we only allow correct puts
}
}
(And it is coincidence that the names are identical! This was written entirely in parallel)