I don't update here often enough, but here's a tidbit I wish I'd found on Google earlier.
Suppose you want to write a Java annotation that has a parameter value, but you want its default value to be null
. Well, too bad. It is illegal to write this annotation:
public @interface Optional { public String value() default null; }
It's a compile time error. javac says "attribute value must be constant;" Eclipse says "The value for annotation attribute Optional.value must be a constant expression." In fact, it's not that surprising, because even if you didn't set a default value, writing this would also be illegal (same error):
@Optional(null)
What the error is saying is that you can't set a Java annotation parameter to null
.
Why is this? The specifications are opaque. JSR-175, which defined annotations for Java 5, just says "If member type is a primitive type or String, the ConditionalExpression must be a constant expression (JLS 15.28)." JLS 15.28, in turn, says that constant expressions can be, for example, any of these:
true (short)(1*2*3*4*5*6) Integer.MAX_VALUE / 2 2.0 * Math.PI "The integer " + Long.MAX_VALUE + " is mighty big."
Notice anything missing? That's right, null
. You can never pass null
as a Java annotation parameter value, because, uh, null
isn't a ConstantExpression.
Why? We may never know. The only thing you can do is workaround it, like this:
public @interface Optional { public String value() default NULL; public static final NULL = "THIS IS A SPECIAL NULL VALUE - DO NOT USE"; }
... and then make your code carefully treat Optional.NULL as if it were really null
.
LAME!