Der folgende Code enthält eine Referenz auf Enum::name
(no no type parameter).
Javac meldet beim Kompilieren eine Warnung:
[WARNUNG] gefunden raw type: java.lang.Enum fehlt Typ Argumente für generische Klasse java.lang.Enum
Wenn Sie den Ausdruck in Enum<T>::name
ändern, wird die Warnung gelöscht.
Allerdings kennzeichnet die Idee die Enum<T>::name
Version mit einer Warnung:
Explizite Argumenttypen können abgeleitet werden
Umgekehrt meldet Eclipse (ECJ) keine Probleme mit beiden Formulierungen.
Welcher der drei Ansätze ist richtig?
Auf der einen Seite sind rohe Typen eher böse. Wenn Sie versuchen, ein anderes Argument vom Typ z. Enum<Clause>::name
wird dazu führen, dass die Kompilierung fehlschlägt, daher gibt es zusätzlichen Schutz.
Andererseits ist die obige Referenz äquivalent zu e -> e.name()
lambda, und diese Formulierung benötigt keine Typargumente.
Umgebung:
Es gibt keine "rohe Methodenreferenz". Zwar gibt es Rohtypen, die die Migration von Code vor der Generierung von Generika unterstützen, es kann jedoch keine Vorgenerics-Verwendung von Methodenreferenzen geben, daher gibt es keinen "Kompatibilitätsmodus", und Typinferenz ist die Norm. Die Java-Sprachspezifikation §15.13. Method Reference Expressions gibt Folgendes an:
Wenn eine Methode oder ein Konstruktor generisch ist, können die Argumente des passenden Typs entweder abgeleitet oder explizit angegeben werden. In ähnlicher Weise können die Typargumente eines generischen Typs, die durch den Methodenreferenzausdruck erwähnt werden, explizit oder abgeleitet bereitgestellt werden.
Methodenreferenzausdrücke sind immer Polyausdrücke
Während Sie also den Typ vor dem ::
als "rohen Typ" aufrufen, wenn er auf eine generische Klasse verweist, ohne Typargumente anzugeben, wird der Compiler dennoch die generische Typ-Signatur gemäß dem Zielfunktionstyp ableiten. Deshalb macht es hier keinen Sinn, eine Warnung vor "roher Typennutzung" zu erstellen.
Beachten Sie, dass z. B.
%Vor% kann mit javac
ohne irgendeine Warnung kompiliert werden (die Spezifikation benennt ähnliche Beispiele, in denen der Typ abgeleitet werden sollte), während
generiert eine Warnung. Die Spezifikation sagt zu diesem Fall:
Wenn
P1
, ...,Pn
nicht leer ist undP1
ein Untertyp von ReferenceType ist, wird der Methodenreferenzausdruck in der zweiten Suche so behandelt, als ob er vorhanden wäre waren ein Methodenaufruf-Ausdruck mit Argumentausdrücken der TypenP2
, ...,Pn
. Wenn ReferenceType ein unformatierter Typ ist und eine Parametrisierung dieses Typs vorhanden ist,G<...>
, also ein Supertyp vonP1
, ist der zu suchende Typ das Ergebnis der Capture-Konvertierung (§5.1. 10) angewendet aufG<...>
; ...
Also sollte der Compiler im obigen Beispiel Enum<Thread.State>
als Parametrisierung von Enum
verwenden, was ein Supertyp von Thread.State
ist, um nach einer geeigneten Methode zu suchen und zum selben Ergebnis wie für das f2
Beispiel zu kommen . Es funktioniert irgendwie , obwohl es die unsinnige Warnung des rohen Typs generiert.
Da javac
diese Warnung anscheinend nur dann generiert, wenn sie nach einem geeigneten Supertyp suchen muss, gibt es eine einfache Lösung für Ihren Fall. Verwenden Sie einfach den genauen Typ zum Suchen:
Dies wird ohne Warnung kompiliert.
Tags und Links java-8 javac method-reference raw-types ecj