On Java Annotations and Type Safety

Posted by & filed under , .

iStock_000008980370XSmallNicolas Fränkel published a blog entry recently talking about “Type-safe annotations” in Java — which trigger my thoughts on the same matter, and voila, there’s this post as a result of it. This is in fact my 2 cents on the matter — and as such I’d recommend you read Nicolas’ point of view too before you decide to embrace fully my approach to this.

Simply put, Nicolas is arguing that the annotation system in Java needs a type safety wrapper around it — for instance if you look at @SuppressWarnings annotation, it accepts a String parameter, which allows any free form string to be used. In the light of that @SuppressWarnings("unchecked") is the same as @SuppressWarnings("UNCHECKED") — except that you will find out that the former will indeed suppress unchecked warnings whereas the latter form will simply be ignored by the compiler (and you will still get the warnings at compile time). Hi argument is that this annotation system should allow for enums to be plugged in so that one can use them (e.g. @SuppressWarnings(SuppressWarnings.UNCHECKED) or the likes.

This looks like a good idea at first — until you start thinking of extensions! If you tie these annotations to an enum then you are preventing anyone from reusing these! (As we know there is no way to extend an annotation in Java and add more members.)

In particular, if you used anything like Checkstyle in your build, you probably found out that Checkstyle warnings can be suppressed also via annotations — by using in particular @SuppressWarnings ! (Have a look in fact at my post about Checkstyle suppressions you will find info on how to do so!) This is simply possible exactly because of the free-form string allowed in this particular annotation.

Now if we ought to apply Nicolas’ approach and have this annotation wrapping an enum, this goes out the window. I’m sure Checkstyle peeps would probably hurry up to offer their own set of annotations for it, however, now your code gets occasionally decorated with @SuppressWarnings (to prevent compile time warnings) and Checkstyle annotations (to prevent Checkstyle warnings). Through FindBugs, PMD,  etc in the mix and you will end up with methods decorated with tons of annotations for each one of the code checks you are running — not pretty!

Instead, because this annotation offers free form text parameters, it can be nicely reused by these tools — so in the worst case scenario you end up with multiple parameters to the same annotation.

The @SuppressWarnings itself is perhaps not a big deal, but there are a few others where I find this helpful (if you ever dealt with serializing JSON or XML and used any of the Jackson libraries you know what I’m talking about).

So I vote for keeping enums out of the annotations — to enable extensions. I do however agree with Nicolas on the fact that there is something to be said about offering a “checked” parameter occasionally in Java annotations.