What are Annotations in Java?

Annotations in Java

  • Annotations in Java are metadata that provide additional information about the code.
  • They do not change the actual execution of the program but offer data that can be used by the compiler, development tools, or frameworks for various purposes, such as code analysis, documentation, or during runtime by frameworks for specific behaviors.

Key Characteristics of Annotations:

  1. Metadata: Annotations provide data about a program but are not part of the program logic.
  2. Declarative: Annotations are declared using the @ symbol, followed by the annotation name.
  3. Support for Tools: Annotations are used by IDEs, compilers, and frameworks for code generation, testing, or runtime processing.

Why Use Annotations?

  • Code Documentation: Annotations like @Override make the code clearer by providing documentation-like information.
  • Compile-time Instructions: The compiler can check annotations for errors or warnings (e.g., @Deprecated can warn the developer that a method is outdated).
  • Runtime Processing: Some frameworks (like Spring) use annotations at runtime to drive behavior, like dependency injection, transaction management, etc.
  • Code Generation: Tools can use annotations to generate code or configuration files (e.g., JAXB for XML binding).

Built-in Annotations in Java

Java provides several built-in annotations that serve different purposes:

1. @Override

  • Indicates that a method is intended to override a method from a superclass.
  • The compiler will throw an error if the method does not actually override a method in the superclass.
  • Example:
class Parent {
    public void display() {
        System.out.println("Parent class method");
    }
}
class Child extends Parent {  

@Override

public void display() { // Overrides Parent’s display method

System.out.println("Child class method");

}

}

2. @Deprecated

  • Marks a method, class, or field as deprecated, meaning it should no longer be used because it may be removed in future versions.
  • The compiler generates a warning if the deprecated element is used.
  • Example:
@Deprecated
public void oldMethod() {
    System.out.println("This method is deprecated");
}

3. @SuppressWarnings

  • Instructs the compiler to suppress specific warnings (like unchecked operations or unused variables).
  • Used for controlling the amount of compiler warnings.
  • Example:
@SuppressWarnings("unchecked")
public void useRawType() {
    List rawList = new ArrayList();  // Raw type usage, usually generates a warning
}

4. @SafeVarargs

  • Suppresses warnings for varargs methods that use generics.
  • Applicable to methods that take a variable number of arguments and use generics.
  • Example:
@SafeVarargs
public final <T> void printElements(T... elements) {
    for (T element : elements) {
        System.out.println(element);
    }
}

5. @FunctionalInterface

  • Marks an interface as a functional interface, meaning it has exactly one abstract method.
  • If the interface does not follow this rule, the compiler throws an error.
  • Example:
@FunctionalInterface
public interface MyFunctionalInterface {
    void execute();  // Single abstract method
}


Meta-Annotations

Java also provides meta-annotations, which are annotations that apply to other annotations. They allow you to define how an annotation behaves.

1. @Target

  • Specifies where an annotation can be applied (e.g., method, field, class).
  • Example values:
  • ElementType.METHOD: Can only be applied to methods.
  • ElementType.FIELD: Can only be applied to fields.
  • Example:
@Target(ElementType.METHOD)  // Annotation can only be applied to methods
public @interface MyMethodAnnotation {
}

2. @Retention

  • Specifies how long the annotation is retained:
  • RetentionPolicy.SOURCE: The annotation is available only in the source code and discarded during compilation.
  • RetentionPolicy.CLASS: The annotation is retained in the .class file but not available at runtime.
  • RetentionPolicy.RUNTIME: The annotation is retained at runtime and can be accessed via reflection.

Example:

@Retention(RetentionPolicy.RUNTIME)  // Annotation is available at runtime
public @interface MyRuntimeAnnotation {
}

3. @Documented

  • Marks that the annotation should be documented in the Javadoc.

4. @Inherited

  • Specifies that the annotation can be inherited by subclasses.

Custom Annotations

  • You can create your own custom annotations in Java by using the @interface keyword.

Syntax:

public @interface MyAnnotation {
    String value() default "default";
    int count() default 0;
}

Example of a Custom Annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
    String description();
}
public class Test {  

@MyCustomAnnotation(description = "This is a test method")

public void testMethod() {

System.out.println("Test method executed");

}

}