Java Annotations Tutorial with examples

Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.

Java annotations were added to Java from Java 5.

Uses of Annotations in Java

Annotations are far more powerful than java comments and javadoc comments. One main difference with annotation is it can be carried over to runtime and the other two stops with compilation level. Annotations are not only comments, it brings in new possibilities in terms of automated processing.

Java annotations are typically used for the following purposes:
  • Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
  • Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
  • Runtime processing — Some annotations are available to be examined at runtime.

Annotations Basics

In its simplest form, an annotation looks like the following:

The at sign character (@) indicates to the compiler that what follows is an annotation. In the following example, the annotation's name is Override:
void myMethod() { ... }

Annotation Elements

The annotation can include elements, which can be named or unnamed, and there are values for those elements:
   name = "Benjamin Franklin",
   date = "3/27/2003"
class MyClass() { ... }

@SuppressWarnings(value = "unchecked")
void myMethod() { ... }

If there is just one element named value, then the name can be omitted, as in:
void myMethod() { ... }

If the annotation has no elements, then the parentheses can be omitted, as shown in the previous @Override example

Repeating annotation

It is also possible to use multiple annotations on the same declaration:
@Author(name = "Jane Doe")
class MyClass { ... }

If the annotations have the same type, then this is called a repeating annotation:
@Author(name = "Jane Doe")
@Author(name = "John Smith")
class MyClass { ... }

Repeating annotations are supported as of the Java 8 release.

Built-in annotations

Java defines a set of annotations that are built into the language.

Annotations applied to Java code:

  • @Override - Checks that the method is an override. Causes a compile error if the method is not found in one of the parent classes or implemented interfaces.
  • public class MySuperClass {
        public void doTheThing() {
            System.out.println("Do the thing");
    public class MySubClass extends MySuperClass{
        public void doTheThing() {
            System.out.println("Do it differently");
  • @Deprecated - Marks the method as obsolete. Causes a compile warning if the method is used.
  • public interface House { 
         * @deprecated use of open 
         * is discouraged, use
         * openFrontDoor or 
         * openBackDoor instead.
        public void open(); 
        public void openFrontDoor();
        public void openBackDoor();
  • @SuppressWarnings - Instructs the compiler to suppress the compile time warnings specified in the annotation parameters.
  • @SuppressWarnings
    public void methodWithWarning() {
  • @SafeVarargs - Suppress warnings for all callers of a method or constructor with a generics varargs parameter, since Java 7.
  • @FunctionalInterface - Specifies that the type declaration is intended to be a functional interface, since Java 8.

Annotations applied to other annotations:

  • @Retention - Specifies how the marked annotation is stored—Whether in code only, compiled into the class, or available at runtime through reflection.
    • RetentionPolicy.SOURCE – The marked annotation is retained only in the source level and is ignored by the compiler.
    • RetentionPolicy.CLASS – The marked annotation is retained by the compiler at compile time, but is ignored by the Java Virtual Machine (JVM).
    • RetentionPolicy.RUNTIME – The marked annotation is retained by the JVM so it can be used by the runtime environment.
  • @Documented - Marks another annotation for inclusion in the documentation.
  • @Target - Marks another annotation to restrict what kind of Java elements the annotation may be applied to.
    • ElementType.ANNOTATION_TYPE can be applied to an annotation type.
    • ElementType.CONSTRUCTOR can be applied to a constructor.
    • ElementType.FIELD can be applied to a field or property.
    • ElementType.LOCAL_VARIABLE can be applied to a local variable.
    • ElementType.METHOD can be applied to a method-level annotation.
    • ElementType.PACKAGE can be applied to a package declaration.
    • ElementType.PARAMETER can be applied to the parameters of a method.
    • ElementType.TYPE can be applied to any element of a class.
  • @Inherited - Marks another annotation to be inherited to subclasses of annotated class (by default annotations are not inherited to subclasses).
  • @Repeatable - Specifies that the annotation can be applied more than once to the same declaration.

Type Annotations and Pluggable Type Systems

Before the Java SE 8 release, annotations could only be applied to declarations. As of the Java SE 8 release, annotations can also be applied to any type use. This means that annotations can be used anywhere you use a type. A few examples of where types are used are class instance creation expressions (new), casts, implements clauses, and throws clauses.

Type annotations were created to support improved analysis of Java programs way of ensuring stronger type checking. The Java SE 8 release does not provide a type checking framework, but it allows you to write (or download) a type checking framework that is implemented as one or more pluggable modules that are used in conjunction with the Java compiler.

For example, you want to ensure that a particular variable in your program is never assigned to null; you want to avoid triggering a NullPointerException. You can write a custom plug-in to check for this. You would then modify your code to annotate that particular variable, indicating that it is never assigned to null. The variable declaration might look like this:

@NonNull String str;

When you compile the code, including the NonNull module at the command line, the compiler prints a warning if it detects a potential problem, allowing you to modify the code to avoid the error. After you correct the code to remove all warnings, this particular error will not occur when the program runs.

Defining own annotations

It is possible to create your own annotations. Annotations are defined in their own file, just like a Java class or interface. Here is an example:
@interface ClassPreamble {
   String author();
   String date();
   int currentRevision() default 1;
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers();

The annotation type definition looks similar to an interface definition where the keyword interface is preceded by the at sign (@) (@ = AT, as in annotation type). Annotation types are a form of interface, which will be covered in a later lesson. For the moment, you do not need to understand interfaces.

The body of the previous annotation definition contains annotation type element declarations, which look a lot like methods. Note that they can define optional default values.

After the annotation type is defined, you can use annotations of that type, with the values filled in, like this:

@ClassPreamble (
   author = "Tutorials Desk",
   date = "09/10/2014",
   currentRevision = 1,
   lastModified = "09/10/2014",
   lastModifiedBy = "Tutorials Desk",
   // Note array notation
   reviewers = {"Tutorials Desk", "Prakash"}
public class Generation3List extends Generation2List {

// class code goes here


To make the information in @ClassPreamble appear in Javadoc-generated documentation, you must annotate the @ClassPreamble definition with the @Documented annotation:

// import this to use @Documented
import java.lang.annotation.*;

@interface ClassPreamble {

   // Annotation element definitions

Marker Annotations

We know what a marker interface is. Marker annotations are similar to marker interfaces, yes they don’t have methods / elements.
 * Code annotated by this team is supreme and need
 * not be unit tested - just for fun!
public @interface SuperTeam { }

public static void readCSV(File inputFile) { }

In the above see how this annotation is used. It will look like one of the modifiers for this method and also note that the parenthesis () from annotation type is omitted. As there are no elements for this annotation, the parenthesis can be optionally omitted.

NEXT READ : Java Custom Annotations Example.

Java Annotations Tutorial with examples

Hope we are able to explain you Java Annotations, if you have any questions or suggestions please write to us using contact us form.(Second Menu from top left).

Please share us on social media if you like the tutorial.