Search code examples
javaarraysannotationscompile-time-constant

Array Constants (Fields) as Annotation Values


While this code happily compiles (with Java 8 / Eclipse Compiler)

public @interface specialized
{
    public Class[] value() default { int.class, long.class, float.class, double.class };
}

Refactoring it to use a constant instead of an array causes an error:

public @interface specialized
{
    public static final Class[] COMMONS = { int.class, long.class, float.class, double.class };

    public Class[] value() default COMMONS;
                                // ^ The value for annotation attribute specialized.value must be a class literal
}

I know that annotation values and -defaults have to be compile-time constants, but although the COMMONS array is technically a compile-time constant, why does this code cause an error? Personally, I think this is extremely counter-intuitive, as it is actually not too much of a pain for the compiler to simply inline this array.

I just realized that they (unsurprisingly) don't work as annotation values either, while they work in both cases in Scala.


Solution

  • COMMONS is an array and therefore not a compile-time constant. Only strings and primitives can be part of compile-time constant expressions. You have to consider that a static final array is still mutable.

    The default value in the example is not a standard array, it's a special language construct called ElementValueArrayInitializer (JLS 9.7.1).