Es gibt sehr wenige Situationen, in denen eine Grenze wie %code% notwendig ist. Die meiste Zeit schreiben die Leute das, die Grenze wird nicht wirklich im Code verwendet, und %code% würde genauso gut funktionieren.
Es gibt jedoch bestimmte Situationen, in denen die Grenze in %code% tatsächlich verwendet wird. Zum Beispiel:
%Vor%Was Ihre Frage angeht - was ist mit %code% ? Nun, das erste Problem ist, dass Sie einen unformatierten Typ verwenden. Rohtypen sollten niemals in neuem Code verwendet werden. Aber Sie sind nicht überzeugt.
Der Rohtyp mit der obigen Klasse ( %code% ) wird mit einer Warnung kompiliert (die Sie auf Ihre eigene Gefahr ignorieren können). Der rohe Typ bedeutet jedoch, dass damit auch unsichere Dinge möglich sind.
Es bedarf einiger Anstrengungen, um ein Beispiel zu finden, um zu zeigen, dass es unsicher ist. Hier ist eins:
%Vor%Der Code wird mit Warnungen, aber ohne Fehler kompiliert und löst zur Laufzeit ein %code% aus.
Betreffend die Aussage
jedes Mal, wenn ich versucht habe, zusätzliche zu entfernen - keine neuen Fehler / Warnungen kamen auf.
Dies sollte nicht der Fall sein. Es sollte eine Warnung ausgegeben werden, weil Sie den rohen Typ %code% verwenden, und das Ergebnis ist fehlende Typsicherheit, wie im Antwort von newacct .
Das %code% / %code% Beispiel ist ein bisschen künstlich und etwas fehlerhaft. Sie haben vorgeschlagen, eine Klasse zu deklarieren
%Vor%Aber hier bedeutet der Typparameter im Grunde: "Dieser Parameter ( %code% ) ist der Typ, mit dem Objekte dieser Klasse ( %code% ) mit" verglichen werden können. Sie sagen also ausdrücklich , dass ein %code% mit %code% vergleichbar sein sollte. Selbst mit anspruchsvollen Sprachen und intelligenten Compilern liegt es in der Verantwortung der Programmierer, Code zu schreiben, der Sinn macht.
Tatsächlich gibt es nicht viele Fälle, in denen diese selbstreferentiellen generischen Typen notwendig sind. Eines dieser Beispiele ist in diesem FAQ-Eintrag skizziert: Er deklariert eine Struktur von Knoten (d. H , ein Baum), wobei der type-Parameter verwendet werden kann, um die Definition der Struktur Struktur vom tatsächlichen Typ der Knoten zu entkoppeln:
%Vor%Aber aus meiner persönlichen Erfahrung kann ich sagen, dass wenn Sie denken, dass Sie einen solchen Typ erstellen müssen, sollten Sie gründlich über die Vor- und Nachteile nachdenken. Letzteres bezieht sich hauptsächlich auf eine verringerte Lesbarkeit. Wenn Sie die Wahl zwischen Methoden wie
haben %Vor%das sind typsicher, oder Methoden wie
%Vor%die nicht typsicher sind (wegen roher Typen oder einfach weil die Typen nicht generisch sind), dann würde ich letztere bevorzugen. Code wird von Menschen gelesen.
Es sieht aus wie zur Zeit hat %code% keinen Vorteil gegenüber %code%
Laut Artikel in Zusammenarbeit mit Java Champions und dem Ersteller von Java Generics FAQ :
Artikel gibt einige Möglichkeiten / Annahmen:
Ich denke, Enum wäre ausreichend gewesen. Allerdings, wie Philip Wadler mich darauf hingewiesen hat, da Enum ein Generikum ist Klasse, sollten wir es immer nur in Verbindung mit einem Typ verwenden. Im Zukünftig könnte Java strenger und rohe Typen werden illegal. Wir haben daher die Wahl, entweder %code% zu schreiben oder %code% , von denen die erste Option mehr ist genau. Auch wenn der Compiler mir momentan keine a zeigt Unterschied, könnte ich in Zukunft Warnungen sehen, also folge ich diesem Idiom meine Klasse auch
Der Unterschied ist, dass %code% zwei Dinge bedeutet:
Umgekehrt bedeutet die Verwendung von %code% :
Der rohe Teil ein Problem, aber die größere Implikation sind die Typgrenzen. Dieser Code demonstriert den Unterschied, wobei die "B" -Klassen die Klassen "A" als generischen Typ verwenden (oder versuchen, sie zu verwenden).
%Vor%Klasse %code% kompiliert gut - der Typ von E ist nur an %code% gebunden, also any %code% Klasse, aber die Klasse %code% löst einen Kompilierungsfehler aus:
Typ Argument SomeTA ist nicht innerhalb der Grenzen der Typ-Variable E
Der Typ von %code% muss genau mit der enthaltenen Klasse übereinstimmen.
Dies ist wichtig, wenn Sie erwarten, dass Parameter und Rückgabetypen mit der Klasse identisch sind, was normalerweise bei typisierten Klassen der Fall ist.
Der Typ, der von einem unformatierten Typ begrenzt wird, ist weniger ein Problem, weil es immer noch ein %code% ist, aber es kann Fälle geben, in denen es einen Unterschied macht (ich kann mir gerade keinen vorstellen).
HINWEIS: Diese Frage ist nicht Enum-bezogen, so dass es nicht doppelt ist. Enum sind gezwungen, nur mit sich selbst zu vergleichen, weil Compiler Generierung von Typ Parameter, nicht, weil Java rekursive Typ Parameter / p>
Ich versuche einen Vorteil zu finden, um eine Klasse zu deklarieren als:
%Vor%versus Erklärung als:
%Vor%Ich habe versucht, Methoden bereitzustellen, die %code% zurückgeben, und Methoden, die %code% zurückgeben, verschiedene Querverweise in komplizierter Klassenhierarchie und jedes Mal, wenn ich versucht habe, zusätzliche %code% zu entfernen - keine neuen Fehler / Warnungen kamen hoch .
Können Sie mir eine Methode zeigen, die den Vorteil dieser zusätzlichen %code% beweist? Ich nehme an, dass es wegen JDK-Deklarationen einen gibt: %code%
Antworten auf andere Fragen zu SO gibt zum Beispiel:
Mit dem zusätzlichen Konstrukt wissen Sie, dass jede Klasse erweitert wird Enum ist nur mit sich selbst vergleichbar.
Aber ich kann diese Theorie leicht brechen:
%Vor%Trotz der generischen Rekursion kann ich immer noch Hund mit Katze vergleichen:
%Vor%Transalting Theorie:
Sie wissen, dass jede Klasse, die Animal ausdehnt, nur mit sich selbst vergleichbar ist
das ist falsch - ich habe einen Klassenhund, der Tier mit Katze ausdehnt, nicht selbst.