Creating custom Annotation in Java
Annotation in Java
- Annotation in Java is a way to provide meta-information related to code element which is used by interpreter and JVM. Here code element include interfaces, classes, fields, methods, arguments and other elements.
- Annotation is represented by
@
sign followed by annotation name. - There are various built-in annotations available in
java.lang
andjava.lang.annotation
. java.lang
have@Deprecated, @FunctionalInterface, @Override, @SafeVarargs, @SuppressWarnings.
java.lang.annotation
have@Documented, @Inherited, @Native, @Repeatable, @Retention, @Target.
In general, we use two meta-annotations @Target
and @Retention.
@Target
It returns an array of ElementType
on which the annotation can be applied to.
ElementType
is an enum which consists of:
As mentioned above @Target
returns an array, so we can also specify multiple targets.
@Retention
@Retention
specify RetentionPolicy
which indicates how long defined annotation is to be retained.
RetentionPolicy
is an enum which consists of:
SOURCE: Annotation will be available in source code only and will be discarded after compilation.
CLASS: Annotation will be available in source code and .class file but, need not to be retained by the VM at runtime.
RUNTIME: Annotation will be available in source code and .class file and, need it is retained by the VM at runtime.
Creating custom annotation
Consider we have an Animal interface which is implemented by Dog and Horse class.
Animal interface has sleep()
method we are going to create @Important
annotation for sleep method.
- Annotations are created same as interface but we need to use
@interface
instead ofinterface
only. - As discussed above,
@Target
and@Retention
are two meta annotations we use generally. - As mentioned in
@Target
this annotation will be utilized on methods only and have retention policy as runtime. - We can define fields as well but we need to write it as
String fieldName()
instead ofString fieldname.
Here, we have definedvalue
to capture meta-information. - If we define fields as
String fieldname();
we need to pass it mandatorily. But we can make it optional usingdefault
, it have default value to be picked if we don’t supply it externally.
That’s all, our @Important
annotation is ready to be used.
Using custom annotation
Let’s discuss the structure of classes for our example.
Now, let’s add sleep method in both Dog and Horse classes.
Dog class will look like this.
And, Horse class will look like this.
We have overridden sleep()
method in both of the classes and added our @Important
annotation. For dog the value passed is “yes” and for horse it is “no”. This is because we will fetch the value and using that to invoke sleep()
method conditionally based on “yes” or “no” value.
Processing custom annotation
- To process custom annotations we need Reflection API.
- If you are not aware of Reflection in Java, please check my article Java Reflection API.
- Before starting, we have used
@Important(value="yes")
for Dogsleep()
and@Important(value="no")
for Horsesleep()
.
- In the above
AnnotationProcessor
class, we are creating objects of Dog and Horse and passing its reference to process it.
- The
processAnnotations(Animal animal)
will take animal as argument. - Then (line 12), we are fetching all the methods available in animal
Class
(visit here to check about Class). - The (line 14), iterating over fetched methods, and checking if
@Important
annotation is present or not. - If
@Important
is present then (line 17), we areImportant
annotation. - Then we are fetching value of
Important
(“yes” or “no”) we have passed. - According to value of
Important
we are executing some logics (print statements here). - The output will be:
Conclusion
As you’ve learned throughout this article, annotations provide a flexible way to associate metadata with code, enabling us to enhance the functionality and enforce constraints. I hope you really enjoyed the article. Happy Learning and Happy Coding! 😊