According to Annotation default "null" value, null values are forbidden as default values in annotations. I wonder why. What is the reason for that?
Note that null
is not only unsupported as default value, it is unsupported as annotation value in general.
JLS §9.7.1 specifies:
It is a compile-time error if the element type is not commensurate with the element value. An element type
T
is commensurate with an element valueV
if and only if one of the following is true:
T
is an array typeE[]
, and either:
If
V
is a ConditionalExpression or an Annotation, thenV
is commensurate withE
; orIf
V
is an ElementValueArrayInitializer, then each element value thatV
contains is commensurate withE
.An ElementValueArrayInitializer is similar to a normal array initializer (§10.6), except that an ElementValueArrayInitializer may syntactically contain annotations as well as expressions and nested initializers. However, nested initializers are not semantically legal in an ElementValueArrayInitializer because they are never commensurate with array-typed elements in annotation type declarations (nested array types not permitted).
T
is not an array type, and the type ofV
is assignment compatible (§5.2) withT
, and:
The last bullet forbidding null
may look arbitrary, but even without that bullet, null
would not be a legal value as it is neither, a constant expression, a class literal, nor an enum constant.
So the last bullet only makes it explicit that this is not an oversight.
When annotations were added to the language, the definition of compile-time constants did already exist, including a bytecode format to store them. Class literals also were syntactically defined, though not on par with constants. But with JDK-4662563, their bytecode format became equivalent to that of other constants in the same version. So the support for class literals was natural for annotations as well.
The only features uniquely added for annotation support were references to enum constants and a storage format for arrays. Both immediately proved their usefulness as the built-in annotations needed for the annotation definition itself, @Retention
and Target
, both use enum constants and the latter also uses arrays.
So, null
was not removed from the set of legal constructs, it has never been added. It was neither, straight-forward or natural to include nor immediately needed for the considered use cases.
This answer shows that a suggestion to add support for null
had been considered initially for the type annotation proposal (see also the archive link), with the objections named right at this point. As we all know, the type annotations were introduced with Java 8, support for null
was not (Other suggestions, like repeatable annotations, made it into the language).