8
votes

Java: Conversion de la liste à la liste Quand Someclass implémente une autre-interfaceface

Je vais avoir une crampe cérébrale: j'ai un interface publique Quelqu'unInterface code> et un SOMECLASS de classe privée statique tente> et essaye de renvoyer une liste code> à partir d'une de mes méthodes, mais je reçois l'erreur (sur la liste de retour ; code> ligne ci-dessous): xxx pré>

Comment puis-je résoudre ce problème sans avoir Pour créer une nouvelle liste? p>

Clarification: Strong> Je ne veux pas que la liste soit créée comme Liste CODE> (Peut-être la solution évidente) parce que Privement je souhaite conserver une liste CODE> pour permettre l'accès futur aux méthodes de Someclass au-delà de celles de l'interface publique. Ce n'est pas montré dans l'exemple ci-dessous, mais dans mon vrai programme, j'ai besoin de cela. P>

import java.util.ArrayList;
import java.util.List;

public class GenericList1 {

    public interface SomeInterface
    {
        public int getX();
    }

    private static class SomeClass implements SomeInterface
    {
        final private int x;
        @Override public int getX() {
            return this.x;
        }       
        public SomeClass(int x) { this.x = x; }
    }

    public static void main(String[] args) {
        List<SomeInterface> list = createList(10);
        printList(list);
    }

    private static void printList(List<SomeInterface> list) {
        for (SomeInterface si : list)
            System.out.println(si.getX());
    }

    private static List<SomeInterface> createList(int n) {
        List<SomeClass> list = new ArrayList<SomeClass>();
        for (int i = 0; i < n; ++i)
            list.add(new SomeClass(i));
        return list;
    }
}


0 commentaires

4 Réponses :


24
votes

Vous devez redéfinir votre méthode comme xxx

et de même, les autres déclarations de la liste. Cela vous permet de gérer des listes génériques polymorphiquement, tant que vous ne lisez que des valeurs d'eux .

(Si vous souhaitez ajouter de nouveaux éléments à une liste, vous devez utiliser < Code> Liste à la place.)

Cet idiome est connu de l'abréviation pecs - producteur: étend / consommateur: super , inventé par Josh Bloch dans l'article 28 de Java, article 28.

Comme d'autres l'ont noté, cet idiome est nécessaire car une liste est pas A Liste , Même lorsque SOMECLASP implémente un individuinterface . La raison de cela est complètement expliquée dans le document référé.


2 commentaires

Ah, ok, cela fonctionne. Dans mon vrai programme, je retourne une liste <> enveloppée par des collections.unmodifiablelist () afin qu'ils vont être en lecture seule.


La réponse avait un lien vers le point 28 mais le lien est maintenant mort. Un fichier PDF du livre est disponible ici: GITUB.COM_LDFAIZTT/CSE331/BLOB/MASTER/...



6
votes

Contrairement à la croyance populaire, Liste n'a absolument aucun lien avec list , même si dérivé étend la base . < P> Juste parce que les classes partagent une hiérarchie ne signifie pas que les collections d'entre elles font. Cela est vrai pour les génériques en général.

Vous pouvez modifier votre code comme suit: xxx


1 commentaires

Oui, c'est la solution évidente mais je ne veux pas faire ça; Voir mes modifications.



0
votes
private static List<SomeInterface> createList(int n) {
    List<SomeInterface> list = new ArrayList<SomeInterface>();
    for (int i = 0; i < n; ++i)
        list.add(new SomeClass(i));
    return list;
}

1 commentaires

C'est la solution évidente mais je ne veux pas faire ça; Voir mes modifications.



1
votes

Je modifierais les signatures des méthodes telles que:

private static void printList(List<? extends SomeInterface> list) {
    for (SomeInterface si : list)
        System.out.println(si.getX());
}

private static <T super SomeClass> List<T> createList(int n) {
    List<T> list = new ArrayList<T>();
    for (int i = 0; i < n; ++i)
        list.add(new SomeClass(i));
    return list;
}


0 commentaires