Java Annotations - Identifier or TypeName

The Java language specification states that the normal annotation is in the format

NormalAnnotation:
@ TypeName (ElementValuePairs opt )

A singleton annotation is in the format:

SingleElementAnnotation:
@ Identifier (ElementValue)

I do not understand why this inconsistency, why there is a normal annotation a TypeName and annotation for one element a Identifier ? I believe that the reference to Identifier may be a mistake in the specification, because the identifier is not qualified, and javac accepts AnnotationDeclarations, which are qualified for both regular annotations and single annotations.

+8
java language-lawyer annotations
source share
4 answers

The reference to Identifier is a mistake in the specification, because the identifier cannot be qualified (you can write @java.lang.SuppressWarnings("unchecked") , but java.lang.SuppressWarnings not a legal identifier). Javac accepts AnnotationDeclarations, which are qualified for both regular annotations and single annotations. The error appears to have been recently introduced; older versions of JLS do not have this problem.

+7
source share

I think there is an error in the grammar documentation. A single annotation element and marker annotations are abbreviated for regular annotation.

You can also see the Java 1.5 / 1.6 specification: http://docs.oracle.com/javase/specs/jls/se5.0/html/interfaces.html#9.7

A singleton annotation is indicated as:

 SingleElementAnnotation: @ TypeName ( ElementValue ) 
+1
source share

The tutorial states that identifiers and type names are two different things. From a programming point of view, this is not so. But from a logical point of view, they can be with the right analogy.

Starting with TypeName : data types (not counting the primitive) and classes usually have more than one method and / or attributes. Thus, TypeName is kind of like the name of a class or data type, which is kind of like.

On Identifier : The identifier is used to denote or describe ONE variable or ONE class. In the right context, an Identifier can be associated with one thing, such as an int value, while TypeName can represent int and String in the same class.

 int Identifier = 90; //Identifier represents an int value class TypeName{ int i; String s; } //TypeName represents an int value and a String TypeName MyNew = new TypeName(); //MyNew references to a TypeName, holding more //than one value 

This is a very careful logic, therefore, if the logic does not make sense to you at first glance, the author may have changed the names for clarity to make them a little different. But no matter what the author calls them, they are one and the same, just formulated in different ways.

0
source share

This is a matter of semantics (and rather pedantic semantics in this).

Consider a NormalAnnotation , for example @SuppressWarnings(value={"foo","bar")) , where SuppressWarnings (TypeName) resolves an annotation class that has a member named value .

Now consider a SingleElementAnnotation , for example @SuppressWarnings({"foo","bar")) . The identifier ( SuppressWarnings ) is the name of the interface, but there is nothing to suggest that one parameter should be assigned value .

So, you cannot parse this sequence of characters directly as NormalAnnotation ; it does not have properly formatted ElementValuePairs . However, if you insert value= between the opening bracket and the beginning of the parameter, then you get something that can be legible as normal.

Similarly for MarkerAnnotation. Missing bracket required by NormalAnnotation.

The identifier must be a value that when used in NormalAnnotation will give a TypeName.

NormalAnnotation has a number of limitations, for example:

This is a compile-time error if TypeName does not name the type of annotation available (ยง6.6) in the place where the annotation is used.

Until SingleElementAnnotation or MarkerAnnotation is converted to NormalAnnotation, SuppressWarnings will be just an identifier and only have to match the definition of Identifier.Note that TypeNames can be qualified, for example java.lang.SuppressWarnings , but identifiers cannot.

I believe the goal was that MarkerAnnotation and SingleElementAnnotation should use simple names (identifiers) rather than fully qualified names (TypeNames). So technically speaking, @Override fine, @java.lang.Override is wrong, but @java.lang.Override() will be allowed. Each compiler I can use allows you to use the latter. This makes the distinction quite controversial for almost everyone.

0
source share

All Articles