Why am I getting an error "Attribute value must be constant". Isn't null constant???
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeInterface {
Class<? extends Foo> bar() default null;// this doesn't compile
}
Try this
It does not require a new class and it is already a keyword in Java that means nothing.
It seem there is one other way of doing it.
I don't like this either, but it might work.
So basically you create an empty Array instead. This seems to allow a default value.
As mentioned, the Java language specification does not allow null values in the annotations defaults.
What I tend to do is to do is to define
DEFAULT_VALUE
constants at the top of the annotation definition. Something like:Then in my code I do something like:
In your case with a class, I would just define a marker class. Unfortunately you can't have a constant for this so instead you need to do something like:
Your
DefaultFoo
class would just an empty implementation so that the code can do:Hope this helps.
I don't know why, but the JLS is very clear:
And the definition of a default element is:
Unfortunately I keep finding that the new language features (Enums and now Annotations) have very unhelpful compiler error messages when you don't meet the language spec.
EDIT: A little googleing found the following in the JSR-308, where they argue for allowing nulls in this situation:
I think only the last two points are relevant to "why not do it in the first place." The last point certainly brings up a good point - an annotation processor never has to be concerned that they will get a null on an annotation value. I tend to see that as more the job of annotation processors and other such framework code to have to do that kind of check to make the developers code clearer rather than the other way around, but it would certainly make it hard to justify changing it.
That error message is misleading, but, no, the
null
literal is not a constant expression, as defined in the Java Language Specification, here.Moreover, the Java Language Specification says
And to explain what that means
So here, your element type,
Class<? extends Foo>
, is not commensurate with the default value, because that value isnull
.It would seem this is illegal, although the JLS is very fuzzy on this.
I wracked my memory to try and think of an existing annotation out there that had a Class attribute to an annotation, and remembered this one from the JAXB API:
You can see how they've had to define a dummy static class to hold the equivalent of a null.
Unpleasant.