Java Programming: Doing your own annotations 
With the release of Java 5 a new feature called annotation showed up. Probably you have already seen it, or even used it.
Basically annotations are metadata you insert in you classes and can be identified by the keyword
@annotation_name.
Maybe you've already used java built-in annotations, such as
@Deprecated or
@Override, but I'm not gonna talk about the existing annotations, I'm writing about how you can create your custom annotation, so let's start.
First of all you have to ask yourself the following:
- What will be the name of the annotation
- What arguments will it receive
Let's now build 2 annotations, one without any arguments - which is commonly called a marker - and one with 2 arguments.
In the first case, programming a marker is as simple as:
package net.pabrantes.annotations
public @
interface MyMarker {
}
Now after compiling it, you can use the new annotation referring to it as
@MyMarker. Although, this being a marker we want to specify that it should be discarded by the compiler. That can be done setting up the
retention policy.
You can set the retention policy to retain the annotation only at the source code by doing the following:
package net.pabrantes.annotations
@Retention(java.lang.annotation.RetentionPolicy.SOURCE)
public @
interface MyMarker {
}
Yes, you just have annotated an annotation! Below you can find a description of each value that the retention policy can take.
| Policy Name | Policy | |
|---|
| SOURCE | Annotation is discarded at compile time | |
| CLASS | Annotation goes into class file but the virtual machine does not retain it | |
| RUNTIME | Annotation goes into class file and and retained by virtual machine. They can then be read by reflection API. | |
You can also annotate an annotation to tell what elements can be annotated, but we will get there later. First, let's build our annotation with two parameters.
Code follows:
package net.pabrantes.annotations
public @
interface MyAnnotation {
public enum SomeSortOfEnum { VALUE1, VALUE2 };
public String parameter1();
public SomeSortOfEnum parameter2();
}
So now you can annotate your code doing the following:
@MyAnnotation(parameter1="a string", parameter2=SomeSortOfEnum.VALUE1 }
public void method(...) { … }
But imagine that you want to allow the programmers to only specify parameter2, and that if no parameter1 is specified it defaults to
"My String". To do that we have to adjust a bit our annotation source code.
package net.pabrantes.annotations
public @
interface MyAnnotation {
public enum SomeSortOfEnum { VALUE1, VALUE2 };
public String parameter1()
default "My String" ;
public SomeSortOfEnum parameter2();
}
Finally imagine that you want to allow the use of this annotation only in methods of a class and the constructors. To do this you have to set the target elements, and that is done using another annotation, called
@Target.
Here is how it can be done:
package net.pabrantes.annotations
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
@Target({METHOD,CONSTRUCTOR})
public @
interface MyAnnotation {
public enum SomeSortOfEnum { VALUE1, VALUE2 };
public String parameter1()
default "My String" ;
public SomeSortOfEnum parameter2();
}
Below you can find a table with all the values of
ElementType.
| Type | Description | |
|---|
| ANNOTATION_TYPE | Declares that the annotation is used to annotate other annotations | |
| CONSTRUCTOR | Declares that the annotation is used to annotate constructors | |
| METHOD | Declares that the annotation is used to annotate methods in the class, constructors are not included in this type | |
| FIELD | Declares that the annotation is used to annotate field declarations | |
| LOCAL_VARIABLE | Declares that the annotation is used to annotate a local variable | |
| PARAMETER | Declares that the annotation is used to annotate a parameter | |
| PACKAGE | Declares that the annotation is used to annotate a package | |
| TYPE | Declares that the annotation is used to annotate a Class, interface or Enum | |
After reading this post I think it's safe to say that you have the necessary knowledge to write your own annotations, although, don't start going nuts writing custom annotations for everything.
Before writing your new custom annotation ask yourself if it's really needed, otherwise you have the risk of excess of annotations in your code, which as you can imagine is not good at all.
- Matthias L. Jugel (matthias.jugel -at- first.fraunhofer.de)
- Stephan J. Schmidt (stephan.schmidt -at- first.fraunhofer.de)
Send them a screenshot along with your font information. And it would rock if you spotted the problem in the CSS.