2011-08-02 9 views
0

Comment déclarer mixedList avec des génériques pour un tel instantané sans modifier le reste du code?Question de conversion rapide en générique

List mixedList = new ArrayList(); 
if(flagA) { 
    ClassA a = new ClassA(); //comes from elsewhere 
    mixedList.add(a) 
} else { 
    List<ClassB> bList = new ArrayList<ClassB>(); //comes from elsewhere 
    mixedList = bList; //error 
} 

Je peux le faire:

List<Object> mixedList = new ArrayList<Object>(); 
if(flagA) { 
    ... 
} else { 
    ... 
    mixedList.addAll(bList); 
} 

mais est-il un moyen d'éviter de modifier le code?

+0

Je ne suis pas sûr de ce que vous voulez dire, si vous le déclarez comme objet, pourquoi devriez-vous changer le reste du code? –

+0

@Oscar: Parce que 'bList' n'est pas assignable à' mixedList'. –

+0

Désolé, j'ai oublié de marquer la ligne avec une erreur. – serg

Répondre

3

Il n'est pas sûr d'affecter bList (List<ClassB>) à mixedList (List<Object>).

Le service auprès duquel vous avez obtenu bList peut conserver une référence à celui-ci; ce service supposera que sa liste contient seulement ClassB instances. Si vous avez été autorisé à affecter cette liste à une référence List<Object>, vous pouvez alors ajouter n'importe quel type d'objet à la liste sans avertissement. Mais lorsque le service, pensant que chaque élément de sa liste était un ClassB, tentait d'accéder aux éléments, un ClassCastException serait levé.

La création d'un nouveau List<Object>, et l'ajout d'éléments avec add() ou addAll(), empêche cette "pollution de type". Vous pouvez modifier cette copie en toute sécurité et laisser la source de la liste conserver sa propre copie "pure".

-1

Il est difficile de savoir ce que vous demandez, en particulier la partie sur "ne pas changer le code" (pourquoi poser une question alors). Néanmoins, il semble que vous pouvez donner une délimitation à la classe pour votre liste:

List<? extends Class<?>> mixedList = new ArrayList<Class<?>>(); 
List<Class<String>> bList = new ArrayList<Class<String>>(); 
bList.add(String.class); 
mixedList = bList; 

Cette compiles de code (chaîne utilisé pour l'enregistrement facile de compilation)

+0

Cela ne ressemble pas à ce qu'il veut, cependant; vous ajoutez juste des classes à la liste, pas des objets de ces classes. –

+0

Oh ouais ... Je vais revenir en arrière et éditer un peu plus tard (occupé maintenant). – Bohemian

0

Je ne crois pas que cela puisse être fait.

Rant:

Java Generics imo sont tout simplement ne vaut pas le mal de tête au-delà de l'utilisation simple collection. Je peux vivre avec des moulages. Et comme nous le savons tous, les génériques donnent le vernis de la sécurité de type mais sous les couvertures il y a un patch de type singe.

/Rant fait:

Cela fonctionne, mais vous devez faire swizzling de référence pour l'un des bloc respectif - ici, je suis en optant pour un List<?> pour mixedList et swizzling pour le cas flagA:

public static void foo(boolean flagA) { 
    List<?> mixedList = new ArrayList<Object>(); 
    if(flagA) { 
     ClassA a = new ClassA(); //comes from elsewhere 
     List<Object> mixedList2 = (List<Object>) mixedList; // mod 
     mixedList2.add(a); 
    } else { 
     List<ClassB> bList = new ArrayList<ClassB>(); //comes from elsewhere 
     mixedList = bList; 
    } 
}