Ich schreibe gerade einen Java-Compiler und habe Abschnitt 15.12.2.7 implementiert. von der JLS7 ( Ссылка ), eins der ärgerlichsten Abschnitte der Spezifikation. Ich habe immer noch ein Problem, da die Spezifikation irgendwie unterspezifiziert oder mehrdeutig erscheint. Mein Problem ist diese Zeile:
lcta (U) =? Wenn die obere Grenze von U Objekt ist, sonst? erweitert lub (U, Objekt)
U ist ein beliebiger Ausdruck. Was ist die Obergrenze eines Typenausdrucks? Außerdem, warum ist die lcta immer ein Wildcard?
Die Spezifikation definiert
Kandidateninvokation (G) = lci (Inv (G)) .
Betrachten wir nun zum Beispiel den Fall, dass Inv (G) = {List & lt; String & gt; h. der einzige mögliche Kandidatenaufruf ist ein einzelner parametrisierter Typ. Nun, aufgrund der Regel
lci (G & lt; X1, ..., Xn & gt;) = G & lt; lcta (X & sub1;), ..., lcta (Xn) & gt; ,
das Ergebnis von CandidateInvocation (G) = lci ({Liste & lt; String & gt;}) würde wie folgt definiert werden:
Liste & lt; lcta (String) & gt;
meiner Meinung nach sollte lcta hier einfach String zurückgeben, denn wenn List & lt; String & gt; ist der einzige mögliche Aufruf, es ist eine gute Idee, List & lt; String & gt; als Argument. Die Definition von lcta (U) schreibt jedoch vor, dass das Ergebnis entweder? oder ? verlängert lub (...), so ist das Ergebnis IMMER ein Wildcard. Das scheint seltsam. Was interpretiere ich hier falsch?
Ich habe in der Compiler-Dev-Mailingliste gefragt und die Antwort erhalten:
Ja, die Spezifikation ist hier falsch. Die Regel für lcta (U) ist einfach totaler Mist :). Außerdem behaupteten sie, dass es sogar besser wäre, lcta (U) überhaupt nicht für ein einzelnes Argument zu nennen und einfach U zu verwenden (da das Argument des kleinsten gemeinsamen Typs eines einzelnen Arguments U immer U selbst sein sollte).
Das sieht wie ein Fehler der Spezifikation aus. Die Klausel von lcta(U)
war in JSL3 nicht vorhanden. Anscheinend ist die Definition von lci(e1..en)
von JLS3 unvollständig, wenn n=1
, und die neue Spezifikation versucht, sie zu beheben. Aber die Lösung scheint Kauderwelsch zu sein, wie Sie meinten.
Javac7 berechnet lci( { List<String> } )
als List<String>
und ignoriert die hinzugefügten Klauseln.
Dieses Problem sollte an die Betreuer von Spezifikationen gestellt werden. nicht sicher, wie man sie kontaktiert. Sie könnten versuchen, openjdk Compiler-dev Mailing-Liste; da sind einige sachkundige Leute drauf.
Tags und Links java compiler-construction type-inference specifications