Peter is a DZone MVB and is not an employee of DZone and has posted 161 posts at DZone. You can read more from them at their website. View Full User Profile

Adding Code to an Annotation

03.15.2012
| 4759 views |
  • submit to reddit
Sometimes you have a framework you would like to be able to add custom annotations to. The problem is; how do you define what this custom annotation does. A possible solution is to use a nested enum.

Nested types

You can nest an interface, a class, an annotation or an enum inside any of these types. e.g.
public class A {
    public interface B {
        public enum C {;
            public @interface D {
                public class E {
                    // etc etc
                }
            }
        }
    }
}
But is this useful or just a novelty?

Adding functionality to an annotation

You can define an interface the framework can call to determine how your custom annotation should behave.
import java.lang.reflect.Member;

/**
* @author peter.lawrey
*/
public interface AnnotationHandler<A> {
    void process(Model model, Member member, A annotation);
}
One way of associating the implementation with the annotation itself is to provide a Singleton enum which implements this interface.
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Member;

/**
* @author peter.lawrey
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
    public int value() default 0;
    
    enum HandlesAnnotation implements AnnotationHandler<CustomAnnotation> {
        INSTANCE;

        @Override
        public void process(Model model, Member member, CustomAnnotation ca) {
            // do something with a model based on the members details and the annotation state.
        }
    }
}
If an annotation could be handled a number of different ways (depending on what process you are performing), you could provide more than one implementation. Using this approach, a framework which uses annotations can allow developers to add custom annotations is a simple manner. The framework can also make it clear how an annotation behaves, making it easier to create annotations which are similar but need to be different in some way.
Published at DZone with permission of Peter Lawrey, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Nicolas Frankel replied on Thu, 2012/03/15 - 5:10am

IMHO, annotations are markers; they shouldn't provide any behavior intrisiquely: on the contrary, annotations should be hints for code to manage the annotated class in a different way.

In this light, while annotations stay the same, different codes would manage the annotated class differently. 

Ronald Miura replied on Thu, 2012/03/15 - 7:10am in response to: Nicolas Frankel

@Nicolas

Enums are typed integer constants, and may be used just like that. But they are also objects, that can have their own methods and attributes. One can use them to create state machines, a simple way to define a set of behaviors (without resorting to lots of ugly switch statements), and Joshua Bloch suggests its use as the simplest way to create serialization-safe singletons (http://java.sun.com/developer/technicalArticles/Interviews/bloch_effective_08_qa.html).

I've never thought about adding code to annotations, but it may be useful in some situations (altough, as anything, it could be badly used, of course). A common approach is to pass a class, which have the code, as a parameter to the annotation (EJB3 interceptors, JSR-303 validators, etc.), which isn't that different anyway.

When (not that long ago) EJB still required interfaces for everything, and you wanted to have only one implementation of some service (which is the most common), a simple way to keep interface and implementation close together was to make the implementation class a static inner class of the interface. Many would say this is a deadly sin and I should burn in Hell, but well, it was very useful, and the code was easier to maintain than to have different classes (or different packages, as some will always preach).

"Nothing is true, everything is permitted" :) 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.