Introduction

Every Java coder, working as a web or enterprise developer would have surely used annotations in Java. Whether in frameworks like Spring, JEE, Struts or in unit testing tools like JUnit, Java annotations are used across all of them. Despite being that common, it is still possible that many Java developers especially beginners do not know what are annotations in Java or how to use them.

We will be further discussing in detail what are annotations in Java, how do they work and how you can use them in your code.

What are annotations in Java?

Java annotations are used to provide metadata for a program written in Java. It provides information about the data used in the program.

Look at the following piece of code for example:

1. @Override
2. public String toString() {
3. return "This is the returning String of this method.";
4. }

In the above code, the toString() method is overridden and the @Override annotation is used here. This code would work perfectly fine if we do not use the annotation but the @Override provides information (metadata) to the compiler that this is an overridden method and if any such method does not exist in a parent class, then a compiler error should be thrown.

The code below demonstrates how you can face a compiler error if the actual method does not exist in your code.

1. class Java_Annotations
2. {
3.      public void display()
4.      {
5.          System.out.println("Base class ");
6.      }
7. }
8. class Derived_Class extends Java_Annotations
9.  {
10.     @Override
11.     public void display(int x)
12.     {
13.         System.out.println("Derived class");
14.     }
15.     public static void main(String args[])
16.     {
17.         Derived_Class obj01 = new Derived_Class();
18.         Obj01.display();
19.     }
20. }

Output :

10: error: method does not override or implement a method from a supertype.

The error indicates that the display() method from the superclass cannot be overridden so we need to either remove parameter (int x) or the @override annotation to successfully compile the program. This compilation error can be helpful for developers as it indicates that the actual method to be overridden does not exist, you must have made a typographic mistake in naming either of the methods. If you would not have used the annotation, the code would compile perfectly fine but you would not get your expected outcome as the mistyped method would be considered as a totally different method.

Annotation placement

As in previous examples, Java annotations are always placed above classes, interfaces, methods or fields.

Here is another example of an annotation added above a class definition:

1. @SampleAnnotation
2. public class class01 {
3.
4. }

The annotation always starts with the @ character, followed by the name of the annotation. In this case, “SampleAnnotation” is written in place of annotation Name.

Built-in annotations in Java

Following are the four most common built-in annotations which are used to give the Java compiler instructions,

  1. @Deprecated
  2. @Override
  3. @SuppressWarnings
  4. @FunctionalInterface

1.     @Deprecated

The @Deprecated annotation is used to label or mark a class, method or field as deprecated, which means that it should not be used. If your code includes deprecated classes, methods or fields, the compiler will execute the code but with a warning.

See this basic @Deprecated annotation example below:

1. @Deprecated
2. public class Annotation_Java {
3.
4. }

The use of the @Deprecated Java annotation above the class declaration marks the class as deprecated. Similarly, it can be used above a method or field declarations, to mark the method or field as deprecated.

2.     @Override

We have already used the @Override Java annotation in previous examples. It is used above the methods that override a method in a superclass. If the method does not match a method in the superclass, the compiler will throw a compilation error.

The @Override annotation is not required to override a method in a superclass but it is considered a good programming practice to use it. With the @Override annotation, the compiler would tell you that the method in the subclass is not overriding any method in the superclass.

Here is an @Override Java annotation example:

1. public class Super_Class {
2.     public void task01() {
3.         System.out.println("this is task01");
4.     }
5. }
6. public class Sub_Class extends Super_Class{
7.     @Override
8.     public void task01() {
9.         System.out.println("Task01 is now overridden");
10.     }
11. }

In case if the definition of the method task01() in Super_Class is altered so the same method in the subclass will no longer override it thus the compiler will generate an error.

3.     @SuppressWarnings

The @SuppressWarnings annotation is used to makes the compiler suppress warnings for any given method. For example, if a method calls a deprecated method, the compiler may generate a warning but it can be suppressed by annotating the method containing the code with the @SuppressWarnings annotation.

This is how you can use @SuppressWarnings annotation:

1. @SuppressWarnings
2. public void methodWithWarning() {
3. 
4. }

4.     @FunctionalInterface

The @FunctionalInterface annotation is used to make sure that the functional interface can not have more than one abstract method. In case if more than one abstract methods are present, the compiler gives an ‘Unexpected @FunctionalInterface annotation’ message/warning. It is not mandatory to use this annotation like other annotations but it is recommended to be used especially while working with functional interfaces.

1. @FunctionalInterface
2. interface calcSquare
3. {
4.     int calculate(int x);
5. }  
6. class Test_Class
7. {
8.     public static void main(String args[])
9.     {
10.         int a = 4;
11.         // lambda expression to define the calculate method
12.         Square sqr = (int x)->x*x;
13.         int answer = sqr.calculate(a);
14.         System.out.println(answer);
15.    }
16. }
Output: 16

How to create Your own annotation in Java?

Java also allows its developers to create their very own annotations commonly known as custom annotations. For that, first annotations are needed to be defined. Similar to a Java class or interface, a custom annotation is needed to be defined in their own file.

See this example of a custom annotation in Java:

1. @interface CustomAnnotation {
2.     String   id();
3.     String   name();
4.     int      age();
5.     String[] newNames();
6. }

This example defines an annotation called @CustomAnnotation. It has four elements. It is to be noted that you need to use the “@interface” keyword to define a custom annotation. This signals to the Java compiler that this is a Java annotation definition.

Each element in an annotation is defined similarly to a method definition in an interface. It has a data type and a name. All primitive data types can be used as element data types but complex objects cannot be used as a data type.

To use the above defined annotation, following code could be used:

1. @CustomAnnotation(
2.     id="abc123",
3.     name="Sam",
4.     age=22,
5.     newNames={"Peter", "Wilson"}
6.  )
7. public class Super_Class {
8.  …
9.  …
10. }

Accessing Java annotations via Java reflection

Usually, an annotation in Java is not present in the Java code after the compilation. Although, it is possible to define your custom annotations that would be available at runtime. These annotations then can be accessed through Java Reflection, to give instructions to your program, or a third-party API. You can do this by annotating your annotation definition with the @Retention annotation.

Here it shows how that can be done:

1. import java.lang.annotation.Retention;
2. import java.lang.annotation.RetentionPolicy;
3. @Retention(RetentionPolicy.RUNTIME)
4. @interface CustomAnnotation {
5.     String   id();
6.     String   name();
7.     int      age();
8.     String[] newNames();
9. }

See the @Retention annotation is placed above your Custom_Annotation definition:

@Retention(RetentionPolicy.RUNTIME)

This line of code signals the Java compiler and JVM that the annotation must be available at runtime through reflection.

Conclusion

As annotations are not compulsory, many Java developers prefer not to use them. Moreover, annotations are often overlooked whenever encountered in someone else’s code but it must have been clear by now how Java annotations can be a great addition to your Java tool kit.

See Also: MVC vs MVP vs MVVM – Top 10 Differences You Should Know

Hopefully, you can now easily answer the question, “what are annotations in Java”. Furthermore, now you have adequate information about annotation in Java to not only work with them but also be able to understand how annotations can be used to improve your code and minimize the chances of making logical errors.

Author

Shaharyar Lalani is a developer with a strong interest in business analysis, project management, and UX design. He writes and teaches extensively on themes current in the world of web and app development, especially in Java technology.

Write A Comment