Home > other >  Java generic T extends Object
Java generic T extends Object

Time:02-03

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 Strings. 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.

  • Related