Annotations in Java

Beknazar
4 min readSep 22, 2021

--

Annotations are the way we can add metadata to class declaration, variable declaration, and methods. We can tag our code with annotations to provide extra information.

@Override
public void run() {
System.out.println("running..");
}

That’s how the annotation looks like. We put the annotation name after @ character.

@Author(
name = "John Doe",
date = "09/14/2021"
)
public class HelloWorld {
}

Some annotations can have elements. name and date are the elements of @Author annotation.

We will discuss these two main topics related to annotations

  1. Built-in annotations in Java.
  2. Creating own custom annotations.

Built-in annotations in Java

There are seven built-in annotations we can use in java. Each of them has its own purpose.

1. @Override This annotation is for method declaration. We can override a parent class/interface method and tag our method with it. It will validate if overriding is done correctly or not. If method overriding wasn’t implemented correctly, it will show a compilation error. Additionally, it helps identify the method overriding without looking to the parent class or interface. It’s good practice always tag overriding methods with this tag.

2. @Deprecated Let’s say you have written libraries for our community to use. By the time you will improve your existing methods, you don’t want to break old code. Usually, the new methods will be created without deleting the old ones. However, you can tag your old method with this tag and people will know that a newer version is available. The IDEs and documentation generators will also reflect this annotation.

3. @SuppressWarnings You can suppress warnings by using this annotation. It can be used in class and method declarations.

4. @Documented This annotation is used when creating our own annotations. It will tell javadoc and similar tools to actually document this annotation(by default annotations are not documented by javadoc).

// example
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface FileWriter {
String filePath();
}

5. @Target is used also to create other annotations. Basically, it will define where we can use this annotation. For example, this annotation can be used only for variable(not local) declarations because we specify so with Target annotation

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNull {
String name();
}

This is a list of possible targets

@Target(ElementType.ANNOTATION_TYPE) - to use in other annotations
@Target(ElementType.CONSTRUCTOR) - to use in contructor declaration
@Target(ElementType.FIELD) - to use in field declarions
@Target(ElementType.LOCAL_VARIABLE) - local variable declarations
@Target(ElementType.METHOD) - to use in method declarions
@Target(ElementType.MODULE) - to use in modules
@Target(ElementType.PACKAGE) - to use in package declaraions
@Target(ElementType.PARAMETER) - to use in parameters
@Target(ElementType.TYPE) - to use in class, interface (including annotation type), or enum declaration
@Target(ElementType.TYPE_PARAMETER) - type prameter declaraion
@Target(ElementType.TYPE_USE) - Use of a type

6. @Retention Firstly, let’s see the definition of this annotation from google

The continued possession, use, or control of something.

This annotation can be applied for annotations only. Basically, it can be used to give a retention policy for other annotations. There are three types of policies available

  1. CLASS — Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.
  2. RUNTIME — Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively. In this mode, it can be used by reflection.
  3. SOURCE — Annotations are to be discarded by the compiler.

7. @Inherited It can be used for annotations only.

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RestClient {
String url();
RequestMethod requestMethod();
String contentType();
}

We created our custom annotation here and tagged with @Inherited. It means when @RestClient will be used in the class declaration, the child classes of this class will inherit @RestClient annotation.

Creating own custom annotations

We can create our own annotations.

What does our @RestClient annotation do? Nothing! Remember annotations are used to give extra data for components and by themself, they are not really much(except built-in ones).

Usually, annotations will be used with java reflections.

Summary

There is a powerful list of built-in annotations in java. They have specific roles and can be quite useful to know them.

We can also built-in our own annotations. In this case, it will be mainly to give extra information for our components(we can think as a comment but more complex). Annotations can be used with java reflection.

Thank you for reading and have a wonderful day!

Credits and resources used:

  1. https://www.geeksforgeeks.org/annotations-in-java/
  2. https://docs.oracle.com/javase/tutorial/java/annotations/basics.html

--

--