Ich habe einen Gehirnkrampf: Ich habe eine public interface SomeInterface
und eine static private class SomeClass
und versuche, eine List<SomeInterface>
von einer meiner Methoden zurückzugeben, aber ich bekomme den Fehler (in der return list;
-Zeile unten) ):
Wie kann ich das beheben, ohne eine neue Liste erstellen zu müssen?
Klarstellung: Ich möchte nicht, dass die Liste als List<SomeInterface>
erstellt wird (vielleicht die offensichtliche Lösung), weil ich privat ein List<SomeClass>
beibehalten möchte, um zukünftigen Zugriff auf die SomeClass-Methoden über das hinaus zu ermöglichen diejenigen in der öffentlichen Schnittstelle. Dies wird im folgenden Beispielfall nicht gezeigt, aber in meinem echten Programm brauche ich das.
Sie sollten Ihre Methode als
neu definieren %Vor%und ähnlich die anderen Listenerklärungen. Dadurch können Sie polymorph mit generischen Listen umgehen, solange Sie nur Werte von ihnen lesen .
(Wenn Sie einer Liste neue Elemente hinzufügen möchten, sollten Sie stattdessen List<? super SomeInterface>
verwenden.)
Dieses Idiom ist unter der Abkürzung PECS - Hersteller: Extends / Consumer: Super bekannt, geprägt von Josh Bloch in Effective Java 2nd Edition, Punkt 28.
> Wie andere bereits festgestellt haben, wird dieses Idiom benötigt, weil List<SomeClass>
nicht a List<SomeInterface>
ist, auch wenn SomeClass implements SomeInterface
. Der Grund dafür wird ausführlich in dem genannten Dokument erläutert.
Entgegen der landläufigen Meinung hat List<Derived>
absolut keine Beziehung zu List<Base>
, auch wenn Derived extends Base
.
Nur weil die Klassen eine Hierarchie teilen, bedeutet das nicht, dass Sammlungen von ihnen tun. Dies gilt für Generika im Allgemeinen.
Sie könnten Ihren Code wie folgt ändern:
%Vor%Ich würde die Signaturen der Methoden wie folgt ändern:
%Vor%Die Verwendung eines Platzhalters in einem Rückgabetyp ist oft eine schlechte Idee, da Sie gezwungen werden, in allen Aufrufmethoden Platzhalter zu verwenden. Ich habe createList eine generische Methode erstellt, so dass der Rückgabetyp so flexibel wie möglich sein kann und trotzdem so spezifisch wie möglich ist.