8

Ich schreibe gerade einen Java-Compiler und habe Abschnitt 15.12.2.7 implementiert. der JLS7 (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.7), einer der nervigsten Abschnitte der Spezifikation. Ich habe immer noch ein Problem, da die Spezifikation irgendwie unterspezifiziert oder mehrdeutig erscheint. Mein Problem ist diese Zeile:Methodentyp Inferenz in der Java-Spezifikation

lcta (U) =? Wenn die obere Grenze von U Objekt ist, sonst? extends 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

CandidateInvocation (G) = LCI (Inv (G)). B. den Fall betrachten, dass Inv (G) = {Liste <String>} ist, d. H. Der einzig mögliche Kandidatenaufruf ist ein einzelner parametrisierter Typ. Nun, aufgrund der Regel

LCI (G < X1, ..., Xn >) = G < lcta (X1), ..., lcta (Xn) >,

das Ergebnis CandidateInvocation (G) = LCI ({List <String>}) würde wie folgt definiert werden: >

meiner Meinung nach < lcta (String)

Liste sollte lcta einf Geben Sie String hier zurück, denn wenn die Liste <String> der einzige mögliche Aufruf ist, ist es eine gute Idee, die Liste <String> als Argument abzuleiten. 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?

Antwort

1

Ich habe in der Compiler-dev Mailing-Liste gefragt und erhielt die Antwort:

Ja, die Angabe falsch ist hier. 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).

6

Das sieht wie ein Fehler der Spezifikation aus. Die Klausel lcta(U) war in JSL3 nicht vorhanden. Anscheinend ist die Definition von JLS3 lci(e1..en) unvollständig, wenn n=1, und die neue Spezifikation versucht, es 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 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.

+0

Ich habe jetzt lcta (U) = U implementiert, die gut zu funktionieren scheint. Ich werde berichten, wenn ich Fälle finde, in denen diese Implementierung zu überraschenden Ergebnissen führt.Übrigens: Ist nicht lub (U, Object) immer U, da Object immer eine Superklasse von U ist und daher der minimierte gelöschte Kandidaten-MEC von {U, Object} immer U oder eine seiner Unterklassen ergeben sollte? Somit ist die Regel wirklich kompletter Mist. Das einzige, wofür es gut sein könnte, ist Verwandlung? erweitert Objekt auf?. Da U jedoch ein Typ-Ausdruck ist, darf er keine Platzhalter enthalten, so dass dieser Fall niemals auftreten kann ... wirklich seltsam. – gexicide

+0

und gute Idee mit der Mailing-Liste, ich denke, ich werde es dort versuchen – gexicide

+0

Ich denke, lub (U, Objekt) = Objekt – irreputable