Annotation Frustrations: not allowing null-valued Annotation properties
Annotations are a great feature that JDK 1.5 brought along. Along with enumerations and generics it vastly improved Java usability. And compared to generics, annotations are rather easy to understand and use.
But considering how good annotations are in general, there are two irritating aspects -- like two sore thumbs -- that sort of ruin perfect harmony between my Java-dev happiness, and Java annotations:
- Inability to use plain old null as annotation value: no, you absolutely can not define null as annotation property value; neither explicitly, nor implicitly (can only omit annotation properties with default value, and default value can not be null)
- Inability to use "any enum value" as value (possibly with generic annotations
Of these, latter is annoying, and prevents some use cases (say, ability
to define an enum and use it as ordered constants for versioning via
annotations), but I can see why there may be technical limitations.
Enumeration implementation is bit convoluted when you get down to
low-level details (just for fun, try to figure out what is the REAL type
of enumeration values, via Introspection... think they are fields? think
again!)
But former... whoever thought that null would be useless as
annotation property value made a huge disservice to Java developers.
Null is absolutely crucial value to have. It's like having numeric
system without value zero.
So why does this matter? Basically, not having null as an option means that one has to create null surrogates: values that imitate nulls. For example, assume that you want to allow adding custom handlers via annotations (for, say, JSON serializer to use for a type): you can define an annotation property with value of Class<IntendedType> (yes, generics work just fine here). But you can not easily make its use optional: so, if you do not want to define such handler (common case), there is no easy way to do it.
The usual work-around, then, is to do two things:
- Create a dummy class (abstract class MyAnnotation.NoHandler extends Handler { } )
- Assign this dummy class as the default value for said property
This works, but is ugly. And gets even uglier when annotation property has String type -- that's where those funky "##default-name##" constants for JAXB come from.
And all this instead of the obvious Right Solution: allowing annotation properties to have value of null. It would be interesting hear plausible explanations for this omission.