Java 8 introduced type annotations with JSR308. According to the Java language specifications
type annotations can be used anywhere a type is used, such as declarations, generic arguments, casts etc.
I'm relatively new to Java, Java 8 was the first version of java I used, so I'm not familiar with non-'type annotations', i.e. declaration annotations.
How are declaration annotations different from type annotations? I want to know because I keep hearing about them in manuals and it looks like 'type annotations' are a superset of 'declaration annotations'.
Both type annotations and declaration annotations still exist in Java, and they are distinct and non-overlapping.
A type annotation can be written on any use of a type. It conceptually creates a new, more specific type. That is, it describes what values the type represents.
As an example, the int
type contains values ..., -2, -1, 0, 1, 2, ...
The @Positive int
type contains values 1, 2, ...
Therefore, @Positive int
is a subtype of int
.
A declaration annotation can be written on any declaration (a class, method, or variable). It describes the thing being declared, but does not describe run-time values. Here are examples of declaration annotations:
@Deprecated
class MyClass { ... }
says that programmers should not use MyClass
.
@Override
void myMethod() { ... }
says that myMethod
overrides a declaration in a superclass or interface.
@SuppressWarnings(...)
int myField = INITIALIZATION-EXPRESSION;
says that the compiler should not issue warnings about code in the initialization expression.
Here are examples that use both a declaration annotation and a type annotation:
@Override
@NonNull String myMethod() { ... }
@GuardedBy("myLock")
@Regex String myField;
Note that the type annotation describes the value, and the declaration annotation says something about the method or use of the field.
As a matter of style, declaration annotations are written on their own line, and type annotations are written directly before the type, on the same line.