Thursday, March 18, 2010

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:

  1. Create a dummy class (abstract class MyAnnotation.NoHandler extends Handler { } )
  2. 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.

blog comments powered by Disqus

Sponsored By

Related Blogs

(by Author (topics))

Powered By

About me

  • I am known as Cowtowncoder
  • Contact me
Check my profile to learn more.