3

According to Annotation default "null" value, null values are forbidden as default values in annotations. I wonder why. What is the reason for that?

mmirwaldt
  • 843
  • 7
  • 17
  • It appears arbitrary to me. That is the reason why I ask. – mmirwaldt Feb 12 '19 at 22:51
  • 1
    The restriction is clear: [due to "grammar"](https://stackoverflow.com/a/1178272/592355)... and (for my)...it makes sense, because `default` is used/wants to overcome some null/empty value, doesn't it? – xerx593 Feb 12 '19 at 22:56
  • ..and! `Object foo();` *has already* the same effect, as you would like to achieve with `Object foo() default null;` ...it is "null, when omit from the annotation"!?;) – xerx593 Feb 12 '19 at 23:03

1 Answers1

5

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 value V if and only if one of the following is true:

  • T is an array type E[], and either:
    • If V is a ConditionalExpression or an Annotation, then V is commensurate with E; or

    • If V is an ElementValueArrayInitializer, then each element value that V contains is commensurate with E.

      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 of V is assignment compatible (§5.2) with T, and:
    • If T is a primitive type or String, then V is a constant expression (§15.29).
    • If T is Class or an invocation of Class (§4.5), then V is a class literal (§15.8.2).
    • If T is an enum type (§8.9), then V is an enum constant (§8.9.1).
    • V is not null.

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).

Holger
  • 285,553
  • 42
  • 434
  • 765
  • Thanks for your extensive answer on that question with all that background and the links. That was what I was looking for when I asked that question. Your answer shows this decision was not arbitrary. – mmirwaldt Jan 15 '21 at 18:59
  • This was massively dumb idea as most of their ideas. Null should be a perfectly valid default value when you need to only sometimes have a real value there and sentinel value is stupid (ie empty class that does nothing just to put in there) – Enerccio Jan 09 '23 at 13:29