Java-Annotationen - Identifier oder TypeName

8

Die Java-Sprachspezifikation besagt, dass a normale Annotation hat das Format

  

NormalAnnotation :
  @ Typname ( ElementValuePairs opt )

Eine Einzelelement-Annotation ist im Format:

  

SingleElementAnnotation:
  @ Bezeichner ( ElementValue )

Ich verstehe nicht, warum diese Inkonsistenz, warum ist eine normale Annotation eine TypeName und eine einzelne Element Annotation eine Identifier ? Ich glaube, der Verweis auf Identifier könnte ein Fehler in der Spezifikation sein, da Identifier nicht qualifiziert ist und javac AnnotationDeclarations akzeptiert, die sowohl für normale Annotationen als auch für Einzelelement-Annotationen qualifiziert sind.

    
Mishax 12.06.2013, 07:30
quelle

4 Antworten

7

Der Verweis auf Identifier ist ein Fehler in der Spezifikation, da ein Bezeichner nicht qualifiziert werden kann (Sie können @java.lang.SuppressWarnings("unchecked") schreiben, aber java.lang.SuppressWarnings ist kein legaler Bezeichner). Javac akzeptiert AnnotationDeclarations, die sowohl für normale Annotationen als auch für Einzelelementanmerkungen qualifiziert sind. Der Fehler scheint kürzlich eingeführt worden zu sein; Ältere Versionen der JLS haben dieses Problem nicht.

    
Mishax 27.07.2013, 05:37
quelle
1

Ich glaube, in der Grammatikdokumentation liegt ein Fehler vor. Das einzelne Annotation-Element und die Marker-Annotationen sind shorthand für die normale Annotation.

Sie können auch die Java 1.5 / 1.6-Spezifikation sehen: Ссылка

Die Einzelelement-Annotation wird wie folgt angezeigt:

%Vor%     
Fedy2 02.08.2013 14:09
quelle
0

Das Tutorial gibt das an Identifiers und TypeNames sind zwei verschiedene Dinge. Aus einer Programmierperspektive sind sie nicht. Aber aus einer logischen Perspektive könnten sie mit der richtigen Analogie sein.

Beginnend mit Typname : Daten Typen (nicht primitive zählen) und Klassen haben in der Regel mehr als eine Methoden und / oder Attribute. In gewisser Weise ist TypeName nett wie der Name einer Klasse oder ein Datentyp, was es ist.

Weiter zu ID : An Identifier wird verwendet, um eine Variable oder EINE Klasse zu benennen oder zu beschreiben. Im richtigen Kontext kann ein Bezeichner mit einer einzelnen Sache wie einem int-Wert verknüpft werden, während ein TypeName einen int und einen String in einer Klasse darstellen kann.

%Vor%

Das ist eine sehr diskrete Logik. Wenn die Logik für Sie auf den ersten Blick keinen Sinn ergibt, hat der Autor die Namen vielleicht geändert, um sie ein wenig anders zu machen. Aber egal, wie der Autor sie nennt, sie sind dasselbe, nur anders formuliert.

    
S0urce C0ded 29.07.2013 18:41
quelle
0

Es ist eine Frage der Semantik (und ziemlich pedantischer Semantik dazu).

Betrachten Sie NormalAnnotation , z. B. @SuppressWarnings(value={"foo","bar")) , wobei SuppressWarnings (der TypeName) in eine Annotationsklasse aufgelöst wird, deren Member value heißt.

Betrachten Sie nun ein SingleElementAnnotation , z. B. @SuppressWarnings({"foo","bar")) . Der Bezeichner ( SuppressWarnings ) ist der Name einer Schnittstelle, aber es gibt nichts, was besagt, dass der eine Parameter value zugewiesen werden sollte.

Sie können diese Zeichenfolge also nicht direkt als NormalAnnotation ; Es hat kein korrekt formatiertes ElementValuePairs . Wenn Sie jedoch value= zwischen der öffnenden Klammer und dem Anfang des Parameters einfügen, erhalten Sie etwas, das als NormalAnnotation analysierbar ist.

Gleiches gilt für MarkerAnnotation. Es fehlt die Klammer, die von der NormalAnnotation benötigt wird.

Der Bezeichner muss ein Wert sein, der bei Verwendung in der NormalAnnotation einen TypeName ergibt.

Die NormalAnnotation hat eine Reihe von Einschränkungen, wie zum Beispiel:

Es ist ein Fehler bei der Kompilierung, wenn TypeName keinen Anmerkungstyp angibt, auf den zugegriffen werden kann (§6.6), wenn die Anmerkung verwendet wird.

Bis die SingleElementAnnotation oder MarkerAnnotation in eine NormalAnnotation umgewandelt wird, ist SuppressWarnings nur ein Bezeichner und muss nur der Definition von Identifikator . Beachten Sie, dass TypeNames qualifiziert werden können, z. B. java.lang.SuppressWarnings , aber IDs nicht.

Ich glaube, die Absicht war, dass MarkerAnnotation und SingleElementAnnotation einfache Namen (Bezeichner) anstelle von vollständig qualifizierten Namen (TypeNames) verwenden sollten. Also technisch sprechen @Override ist ok, @java.lang.Override ist falsch, aber @java.lang.Override() wäre erlaubt. Jeder Compiler, den ich in die Finger kriegen kann, erlaubt Letzteres. Das macht die Unterscheidung für fast jeden ziemlich strittig.

    
Devon_C_Miller 02.08.2013 05:16
quelle