Do annotations apply to all variables in a declaration statement?

  • A+

If multiple fields are declared in a single statement using a field annotation, does the annotation apply to all of the fields?

For example, will the following result in x, y, and z all having the @Nullable annotation?

@Nullable public Integer x, y, z; 

I'm looking for an official specification on this, but have had trouble finding one.


I think the closest we can get is this, starting from §8.3:

FieldDeclaration:   {FieldModifier} UnannType VariableDeclaratorList ;  VariableDeclaratorList:   VariableDeclarator {, VariableDeclarator}  VariableDeclarator:   VariableDeclaratorId [= VariableInitializer] 

And FieldModifier is:

FieldModifier:   (one of)   Annotation public protected private   static final transient volatile  

(So an annotation is a field modifier.)

And back to §8.3:

More than one field may be declared in a single FieldDeclaration by using more than one declarator; the FieldModifiers and UnannType apply to all the declarators in the declaration.

So in otherwords, given:

@Nullable public Integer x, y, z; 

We know that the field modifiers @Nullable public apply to all of x, y and z.

Also, reading a bit more of §8.3 as well as §9.74 will clarify that that's the case even if @Nullable is declared as a type annotation (i.e. @Target(ElementType.TYPE_USE)):

It is possible for an annotation to appear at a syntactic location in a program where it could plausibly apply to a declaration, or a type, or both. This can happen in any of the five declaration contexts where modifiers immediately precede the type of the declared entity:

  • […]

  • Field declarations (including enum constants)

  • […]

The grammar of the Java programming language unambiguously treats annotations at these locations as modifiers for a declaration (§8.3), […].

In other words, an annotation in such a location is always treated syntactically as a field modifier, even if it's not considered a declaration annotation (because it's not declared with @Target(ElementType.FIELD)). This is also hinted at in the grammar for field declarations, where the type is given as UnannType, i.e. unannotated type.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: