1

Here is my code. The compiler refuses to compile it :

private transient List<? extends Map<String, Object>> donnees;

// ...

public <M extends Map<String, Object>> void addDonnee(M nouvelleDonnee) {
    getDonnees().add(nouvelleDonnee);
}

public List<? extends Map<String, Object>> getDonnees() {
    // ...

    return donnees;
}

Why do I get this error ?

The method add(capture#4-of ? extends Map<String,Object>) in the type List<capture#4-of ? extends Map<String,Object>> is not applicable for the arguments (M)

EDIT Here how I solve my problem :

private transient List<Map<String, Object>> donnees;

// ...

public void addDonnee(Map<String, Object> nouvelleDonnee) {
    getDonnees().add(nouvelleDonnee);
}

public List<Map<String, Object>> getDonnees() {
    // ...

    return donnees;
}

And now the compiler is happy ! :)

Stephan
  • 41,764
  • 65
  • 238
  • 329
  • Check the answer of [Jack](http://stackoverflow.com/questions/1684121/generics-error-not-applicable-for-the-arguments) – GokcenG Aug 22 '13 at 11:52

4 Answers4

3

The getDonnees method returns a list of "something" that implements Map<String,Object>. It could be a list of TreeMaps, or of HashMaps for example; there's no way to know.

Since you don't know the exact component type of the list, you can't add anything to it. For example, you could be trying to add a HashMap to a list of TreeMap.

The two methods should use the same parameter somehow, for example one declared with the class:

class SomeClass<M extends Map<String, Object>> {

  public void addDonnee(M nouvelleDonnee) {
    getDonnees().add(nouvelleDonnee);
  }

  public List<M> getDonnees() {
    // ...
    return donnees;
  }
}
Joni
  • 108,737
  • 14
  • 143
  • 193
3

Both ? and M are subclasses, and may not be castable into each other. Try declaring donnees:

private transient List<Map<String, Object>> donnees;
Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
András Hummer
  • 960
  • 1
  • 17
  • 35
1

You cannot insert anything into a List defined as List<? extends Foo>.

This is discussed in a decent level of detail in the JDK documentation (see the bottom of the page).

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
1

Java is complaining because it doesn't know that the types of donnees, addDonnee and getDonnees are the same. The one could be a List<HashMap<String, Object>>, while the others can be a List<TreeMap<String, Object>>, which are not compatible (you can't add a HashMap to a List<TreeMap> and vice versa).

You can add a generic parameter to the class instead:

public class SomeClass<T extends Map<String, Object>>
{
  private transient List<T> donnees;

  public void addDonnee(T nouvelleDonnee) {
      getDonnees().add(nouvelleDonnee);
  }

  public List<T> getDonnees() {
      return donnees;
  }
}
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138