-->

Method call doesn't match method signature eve

2019-09-13 00:51发布

问题:

This question already has an answer here:

  • Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic? 16 answers

The method:

public static void incrementMapCounter( Map<Object,Number> tabulationMap, Object key ) {
  Number value = 0;
  if ( tabulationMap.containsKey(key) ) {
    value = tabulationMap.get(key);
  }
  value = value.doubleValue() + new Double(1);
  tabulationMap.put( key, value );
}

Call to the method:

Map<String,Long> counts = new HashMap<>();
String key = "foo-bar";
incrementMapCounter( counts, key );

Error (reformatted):

The method
    incrementMapCounter(Map<Object,Number>, Object)
in ... is not applicable
    for the arguments  (Map<String,Long>, String)

The method signature is either a matching type or more generic:

  • Map is a Map
  • String is an Object (x2)
  • Long is a Number

I'm a bit confused on this one.

回答1:

It's the later two. String and Object are not the same type. Generics are not covariant, they are invariant. The types have to match exactly. Same with Long and Number.

For your method signature you might try:

public static <T> void incrementMapCounter( Map<? extends T, ? extends Number> map, T key )
{ ...

Which can be called by:

 HashMap<String, Integer> myMap = new HashMap<>();
 incrementMapCounter( myMap, "warble" );


回答2:

Generics are invariant so the arguments will need to match the arguments passed in so that values can be added to the Collection

public static void incrementMapCounter(Map<String, Long> map, Object key) {