E.G. Um eine ArrayList von Strings zu erstellen, müssen wir etwas wie
machen %Vor%, während es in der Lage sein sollte, den Parametertyp für den Konstruktor abzuleiten, so dass wir nur
eingeben müssen %Vor%Warum kann der Typ nicht auf die gleiche Weise eingegeben werden wie Typparameter für generische Methoden.
Dies ist eine Java 7-Verbesserung, die auch als Diamantoperator bekannt ist. Die Syntax lautet:
%Vor%Der offizielle Vorschlag , der in Project Coin aufgenommen werden soll lautet Verbesserte Typinferenz für generische Instanzerstellung
Nach Rémi Forax ist die Änderung bereits in der mercurial-Repository.
Wie andere bereits gesagt haben, ist dies in der Liste für Java 7 . Ich möchte jedoch darauf hinweisen, dass die Google-Sammlungsbibliothek dies bereits für verschiedene Sammlungen unterstützt. wenn Sie gerne statische Importe verwenden. Zum Beispiel schreibe ich häufig Code wie:
%Vor% Sie brauchen nur den statischen Import und entfernen den Abstand zwischen new
und ArrayList()
:)
(Der statische Import wäre in Lists
class, übrigens. Es gibt ähnliche Methoden für Karten etc.
Es kann sein und es ist eine Funktion, die für die Aufnahme in JDK7 vorgesehen ist.
Sie wollen einen Grund, warum das aktuelle Java es nicht unterstützt.
Ich kann nur sagen, dass Java in der Regel nur kleine Schritte unternimmt. Ich würde vermuten, dass es einen kleinen technischen Fehler gab, dass sie nicht sicher waren, ob sie vor Java 7 "richtig" waren - wahrscheinlich etwas damit zu tun, absolut sicher zu sein, dass es keinen mehrdeutigen Fall in irgendeinem älteren oder nicht-generischen Code erzeugen würde .
Beachten Sie, wie Robert darauf hingewiesen hat, dass die Syntax so aussehen wird:
%Vor%Beachten Sie das leere & lt; & gt; Ich vermute, das ist, um diese Art von Schlussfolgerung aus älteren nicht-generischen Code zu disambiguieren; es ist wahrscheinlich nur etwas, an das sie zuerst nicht gedacht haben.
Der Typ kann abgeleitet werden, aber die Autoren haben einfach entschieden, dass es besser ist, überhaupt keine Typrückschlüsse zu haben, dann haben sie in einigen Fällen eine begrenzte Art von Inferenz.
Wenn Sie Inferenz auf jvm eingeben möchten, schauen Sie sich scala an.
Ich bin kein Java-Experte, daher bin ich mir nicht ganz sicher, was ich sagen werde. Hier sind meine Gedanken:
Da Java Generics durch Löschen implementiert, gibt es für jeden generischen Typ einen zugrunde liegenden unformatierten Typ. Wenn Sie einen generischen Typ definieren, wird ein zugrunde liegender unformatierter Typ verwendet, der Object
rundum verwendet.
Wenn Sie ein neues ArrayList
instanziieren, wäre es falsch, wenn der Compiler den Typparameter aus der Instanziierungsklasse ( ArrayList<String>
in Ihrem Beispiel) ableitet, da es eine Klasse mit genau diesem Namen und keinem Typparameter gibt ( das ist der Rohtyp ArrayList
). Ich denke auch, dass dies der Grund ist, warum Sie in Java 7 <>
zum Konstruktoraufruf hinzufügen müssen, um dem Compiler mitzuteilen, dass er den Typ ableitet.
Man könnte argumentieren, dass der Compiler den Raw-Typ nur dann instanziieren sollte, wenn die Definitionsklasse der Raw-Typ ist, aber ich denke, dass dies verwirrend wäre. Ich denke, dass der Compiler auf unvollständige Ausdrücke schließen muss, die ohne einen gegebenen Kontext ungültig wären, was bei der new ArrayList()
-Anweisung nicht der Fall ist.
Ich hoffe, das ist klar, und wenn ich falsch liege, kann mich jemand korrigieren.
Seitliche Anmerkung:
Beachten Sie auch, dass die rohe Klasse nicht mit dem Typ identisch ist, der Object
als Typparameter verwendet:
ist gültig, wo wie
%Vor%ist nicht. Im ersten Fall kann der Raw-Typ wie ein generischer Typ verwendet werden, im zweiten Fall jedoch die Kontravarianz, die nicht verfügbar ist (nicht, wenn Sie keine Platzhalter verwenden).