Given the following class:
public class TestMap<K,V> {
private HashMap<K,V> map;
public void put(K k, V v) {
map.put(k, v);
}
public V get(K k) {
return map.get(k);
}
}
and this function:
static<T extends Object> String getObj(TestMap<T, String> m, String e) {
return m.get(e);
}
Why does "get" show this error:
The method get(T) in the type MyHashMap<T,String> is not applicable for the arguments (String)
When getObj
states T extends Object
, and the map has been initialized with TestMap<T, String> m
, why can't String be used as parameter? I cant wrap my head around why this doesnt work, as String is a subtype of Object ?
I tried extending T from a custom superclass and using a subclass instead of String.
CodePudding user response:
get()
requires as an argument a key, which is of type T
, not String
.
So either you need to change e
to type T
or change the type of the Map
, e.g., to TestMap<String, T>
.
CodePudding user response:
Generics describe what an Object is, List<String> strings
is a list of String
s. That gives us some convenience, we don't have to cast. String s = strings.get(0);
and we get some compile-time protection. Integer i = 1;
then strings.add(i);
fails to compile.
The error you are getting is a compile time protection. The key you're providing is an Object, so it might be the correct type. In the case of a map, "why not check?" It is just going to hashcode and check for equality which is ok. In the case of a List though, strings.add((Object)i);
needs to fail.
If the doesn't fail, then later something might call. for(String s: strings)
and get a class cast exception.
To fix this you can change you V get(K k)
method to a V get(Object k)
the same as map uses. Your get method requires type K
a map normally has a get method with a Object
As mentioned "T extends Object" is the same as just "T". You use the extends when you want to put a lower bound on something. public <T extends Number> int sum(List<T> numbers)
. In this case "T" can be any class that extends numbers. We can do Number n = numbers.get(0);
because we know it is at least a number. But we could not do numbers.add(n);
because while T
is at least a number, it could be something else like an Integer, Double, Number, BigDecimal etc.