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.
Devon_c_miller
source share