Two ways to declare a generic java method

For now, there are similar questions, such as this and this ; they don’t answer, what is the difference between the two ways of declaring generic and why one of them compiles, but the other is not in the following example?
The one that does not compile was based on the official textbook , as on me.

public void processMap1(Map<String, List<?>> map) {
}

public <T> void processMap2(Map<String, List<T>> map) {
}

public void f() {
    Map<String, List<String>> map = new HashMap<>();

    processMap1(map); // ERROR
    processMap2(map); // OK
}

I want my methods to work both with Map<String, List<String>>andMap<String, List<Object>>

+2
source share
1 answer

You have a method that expects an object of type X. To pass an object to this method, this object must have a type Ythat is a subtype X.

:

void processNumber(Number number) { ... }
void callIt()
{
    Integer integer = null;
    processNumber(integer); // Fine. Integer is a subtype of Number

    String string = null;
    processNumber(string); // Error. String is NOT a subtype of Number
}

. . : - ?:

, , FAQ.

, (), , .


, , , . , , , Map<String, List<String>>, , T String . T String, . ( , )


, , , . : , , . :

Map<String, List<String>> Map<String, List<?>>

( ) , :

Map<String, List<String>> map = new HashMap<>();
Map<String, List<?>> otherMap = map; // Does not work

, " " FAQ, , , , , : A Map<String, List<?>> - , , / . , processMap1:

public void processMap1(Map<String, List<?>> map) 
{
    List<Number> numbers = new ArrayList<Number>();
    map.put("x", numbers);
}

, Map<String, List<String>> :

public void f() {
    Map<String, List<String>> map = new HashMap<>();
    processMap1(map); // Imagine this was possible
    List<String> shouldBeStrings = map.get("x");
}

ClassCastException, Map<String, List<String>> , List<Number> .

: , .


( , , ):

T . ?, , , . reverse rev , T - ?, , . , :

List<T> List<?> ( , T)

processMap1 processMap2 , : Y X, Map<String, Y> Map<String, X>. .

+3

All Articles