public interface A {
    int getA();
}

public class MyObj implements A {
    public int getA(){
        return 1;
    }
}

Si vous avez une carte: Map<? extends A, String> aMap = new HashMap<>();

Comment puis-je ajouter un MyObj à ce aMap? Ou comment devrait être la classe MyObj pour qu'elle puisse fonctionner dans cette carte

2
Elie Daher 16 janv. 2017 à 15:35

2 réponses

Meilleure réponse

Comment puis-je ajouter un MyObj à ce aMap?

Vous ne pouvez pas, à cause de la limite supérieure du type de clé.

La raison en est que ? extends A pourrait être MyOtherObj implements A. Dans ce cas, il serait de type unsafe de pouvoir mettre une clé de type MyObj dans la carte:

Map<MyOtherObj, String> anotherMap = new HashMap<>();

Map<? extends A, String> aMap = anotherMap;
aMap.put(new MyObj(), "");  // Can't do this; but if you could...

MyOtherObj obj = anotherMap.keySet().iterator().next();  // ClassCastException!

Rappelez-vous l'acronyme PECS (voir cette question pour beaucoup plus de détails) :

  • Producteur extends
  • Consommateur super

En d'autres termes, Map<? extends A, String> ne peut être utilisé que pour produire des instances de A, il ne peut pas consommer / accepter des instances de A.

Par exemple, vous pouvez itérer les clés ("produire" les clés):

for (A a : aMap.keySet()) { ... }

La carte ne peut "consommer" qu'un littéral null:

aMap.put(null, "");

Car null peut être converti en n'importe quel type sans exception. Mais il n'y a pas beaucoup d'utilité dans une carte qui n'a qu'une seule clé - vous pouvez aussi simplement stocker la valeur directement.

La seule façon de faire ce type en toute sécurité est de placer l'instance de MyObj dans la carte via une référence que vous savez accepte les instances MyObj:

Map<MyObj, String> safeMap = new HashMap<>();
safeMap.put(new MyObj(), "");

Map<? extends A, String> aMap = safeMap;

Ou

Map<A, String> safeMap = new HashMap<>();
safeMap.put(new MyObj(), "");

Map<? extends A, String> aMap = safeMap;

Mais vous devriez envisager de ne pas avoir du tout la carte typée générique; Map<MyObj, String> ou Map<A, String> est plus simple.

6
Community 23 mai 2017 à 11:45

Ce n'est pas possible. Votre compilateur ne le permettra pas.

Vous devez changer votre carte en:

Map<A, String> aMap = new HashMap<>();

Après cela, vous pouvez utiliser put pour y ajouter un élément:

aMap.put(new MyObj(), "myObject");
2
King Nike 16 janv. 2017 à 12:53