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
  • 40,082
  • 60
  • 228
  • 319
  • 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
  • 105,306
  • 12
  • 136
  • 187
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
  • 63,838
  • 26
  • 184
  • 242
András Hummer
  • 940
  • 1
  • 16
  • 33
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
  • 63,838
  • 26
  • 184
  • 242
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
  • 52,963
  • 14
  • 96
  • 130