Die innere statische Klasse innerhalb der inneren Klasse kann nicht konvertiert werden

8

Inspiriert in dieser Frage: Wie Iterable implementiert wird Ich habe mich entschieden, eine einfache verkettete Listenimplementierung zu machen und einen Iterator zu implementieren Um einen Code wie folgt zu haben:

%Vor%

Der Code war nicht schwer zu bearbeiten, indem ein class MyList<T> implements Iterable<T> mit einem private static class Node<T> und einem private class MyListIterator<T> implements Iterator<T> erstellt wurde, aber dann stieß ich auf ein Problem bei der Implementierung meiner eigenen Version von Iterator#remove :

%Vor%

Diese Fehlermeldung hat mich neugierig gemacht. Ich habe im Internet nach diesem Problem gesucht, aber nichts gefunden (oder wahrscheinlich bin ich nicht so gut darin, diese Art von Problemen zu suchen). Was wäre der Grund dafür, dass zwei Variablen des gleichen Typs verglichen, aber nicht einander zugeordnet werden können?

Übrigens weiß ich, dass ich mir einfach den Code von LinkedList ansehen und überprüfen kann, wie die Java-Designer das implementiert haben, und kopiere / füge es an meine eigene Implementierung an, aber ich bevorzuge eine Erklärung und ein Verständnis von dem wirklichen Problem.

Kompletter Code, der meine aktuelle Implementierung von MyList class zeigt:

%Vor%     
Luiggi Mendoza 02.07.2013, 22:06
quelle

4 Antworten

16

Das ist das Problem:

%Vor%

(Es hilft nicht, dass Sie in Ihrer reduzierten Version MyList nicht-generisch gemacht haben.)

An diesem Punkt gibt es zwei verschiedene T -Typ-Variablen - die eine in der geschachtelten Klasse und die eine in der äußeren Klasse. Sie brauchen Node nicht, um generisch zu sein - Sie brauchen nur:

%Vor%

Jetzt gibt es nur eins T - dasjenige in der äußeren Klasse. Es ist nicht so, dass der Listen-Iterator ein anderes T haben soll als das, das in der umschließenden Instanz deklariert wurde, also sollte es nicht generisch sein.

Um es anders auszudrücken: Versuchen Sie MyListIterator generic in einem Typparameter mit einem anderen Namen zu machen, und dann wird es klarer, was schief läuft, da die beiden Namen in der Fehlermeldung unterschieden werden können. Es ist effektiv:

%Vor%

(oder umgekehrt).

    
Jon Skeet 02.07.2013, 22:15
quelle
7

Der Iterator sollte als

deklariert werden %Vor%

und nicht als

%Vor%

Indem es als MyListIterator deklariert wird, ist sein generischer Typ T nicht das selbe T wie das T von seiner einschließenden Klasse.

    
JB Nizet 02.07.2013 22:15
quelle
6

Entfernen Sie den Typparameter aus der Deklaration von MyListIterator :

%Vor%

und der Aufruf in iterator()

%Vor%

In Ihrer aktuellen Version ist das T von MyListIterator nicht das gleiche T wie das in MyList .

    
Ian Roberts 02.07.2013 22:14
quelle
2

Die anderen drei haben Recht: Sie müssen ändern private class MyListIterator<T> implements Iterator<T>
zu
private class MyListIterator implements Iterator<T>
Aber wenn du das einmal getan hast, musst du auch deine iterator() -Methode ändern:

%Vor%

Sonst erhalten Sie einen weiteren Fehler. Sobald Sie die zweite Änderung vornehmen, sollte es funktionieren.

    
Chuck Rittenhouse 02.07.2013 22:23
quelle