I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this article, we’ll have a look at the available, built-in annotations in Java.

2. What is an Annotation?

Simply put, annotations are a form of metadata that can be added to classes, fields, and methods.

Names of annotation types start with the “@” sign:

@Deprecated
public class MyClass { ... }

Annotations serve multiple purposes like:

  • Compiler Information: they can be read by it and used for additional processing
  • Runtime Information: annotations can be read during runtime (for example, this approach is used heavily in the Spring ecosystem)

3. List of Built-In Annotations in Java

3.1. @Deprecated

@Deprecated can be used to indicate that an element is deprecated:

@Deprecated
void deprecatedMethod() { }

If we use this deprecatedMethod anywhere in our code, the compiler will report a warning.

3.2. @Override

@Override tells the compiler that the element is meant to override an element declared in a superclass:

interface MyOperation {
    void perform();
}

class MyOperationImpl implements MyOperation {

    @Override
    public void perform() { }
}

Using @Override isn’t mandatory but if we annotate a method which doesn’t override any method (or doesn’t match the signature), the compiler will generate an error.

3.3. @SuppressWarnings

@SuppressWarnings tells the compiler to suppress specific warnings:

@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
    deprecatedMethod();
}

Every warning belongs to its own category. If we want to suppress multiple categories of warnings we can pass all of them as an array:

@SuppressWarnings({"unchecked", "deprecation"})

3.4. @SafeVarargs

By applying the @SafeVarargs to a method or a constructor, we assert that the code doesn’t perform potentially unsafe operations on the varargs parameter.

When using this annotation, any related unchecked warnings get suppressed as well.

3.5. @FunctionalInterface

@FunctionalInterface indicates that the type declaration is intended to be used as a functional interface which means that it can only have one abstract method. 

Let’s look at a quick example:

@FunctionalInterface
public interface IntConsumer {
    void accept(Integer number);
}

4. Meta-Annotations

Annotations that apply to other annotations are called meta-annotations. Now let’s look at the built-in ones defined in Java.

4.1. @Retention

@Retention specifies the retention strategy:

  • RetentionPolicy.SOURCE – retained only in the source and is ignored by the compiler
  • RetentionPolicy.CLASS – available at compile time but not at runtime
  • RetentionPolicy.RUNTIME – available at runtime and can be accessed using reflection

4.2. @Documented

By using @Documented we specify that when JavaDoc is generated from our source code the specified annotation should shop up in the resulting document.

4.3. @Target

@Target restricts possible places where the annotation can be used.

We have a few options:

  • ElementType.ANNOTATION_TYPE can be applied to an annotation type
  • ElementType.CONSTRUCTOR can be used on a constructor
  • ElementType.FIELD we can add it to a field or property
  • ElementType.LOCAL_VARIABLE we can use it on a local variable
  • ElementType.METHOD can be applied on the method-level
  • ElementType.PACKAGE applies 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

Let’s look at an example:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.LOCAL_VARIABLE, ElementType.FIELD})
@interface MyAnnotation {
    // 
}

class MyTarget {

    @MyAnnotation
    String someField;

    @MyAnnotation // invalid!
    public void doSomething() {

        @MyAnnotation
        String localVariable;
    }
}

4.4. @Inherited

It can be used to indicate that an annotation can be inherited from a superclass. When a user checks the annotation type from a class and it has no annotation for this type, the class’ superclass is checked for the annotation type.

4.5. @Repeatable

@Repeatable indicates that the annotation can be applied more than once on a given target.

Let’s define @Interval which indicates how often periodic cleanup should be performed:

@Repeatable(Intervals.class)
@interface Interval {
    int hour() default 1;
}

@interface Intervals {
    Interval[] value();
}

@Interval(hour = 17)
@Interval(hour = 13)
void doPeriodicCleanup() {
}

5. Conclusion

This article showed us what built-in annotations are present in Java, how they can be used and why they are useful.

Code snippets can be found over on GitHub.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS

Leave a Reply

Be the First to Comment!

Notify of
avatar