What are Annotations? Explain the following built-in annotations

1.B] What are Annotations? Explain the following built-in annotations with an example program:
i) @Override
ii) @Inherited
iii) @Retention

Answer:

Annotations in Java:

Annotations in Java provide metadata about the program and can be used to give instructions to the compiler, runtime, or other tools. They are a form of syntactic metadata that can be applied to classes, methods, fields, parameters, and other elements. Annotations do not directly affect the execution of a program but can be used by frameworks, libraries, and tools for various purposes such as code generation, validation, and documentation.

Built-in Annotations:

i) @Override:

  • Definition:
    The @Override annotation indicates that a method is intended to override a method declared in a superclass. This annotation helps the compiler catch errors if the method does not correctly override a method in the superclass.
  • Example:
  class Parent {
      void display() {
          System.out.println("Parent class display method");
      }
  }

  class Child extends Parent {
      @Override
      void display() {
          System.out.println("Child class display method");
      }
  }

  public class OverrideExample {
      public static void main(String[] args) {
          Parent obj = new Child();
          obj.display();  // Calls the overridden method in Child class
      }
  }
  • Explanation:
    In this example, the display() method in the Child class overrides the display() method in the Parent class. The @Override annotation ensures that if the method signature in the Child class does not match the one in the Parent class, the compiler will throw an error.

ii) @Inherited:

  • Definition:
    The @Inherited annotation indicates that an annotation type is automatically inherited by subclasses. If a superclass is annotated with an annotation that is marked as @Inherited, the subclass will automatically inherit the annotation.
  • Example:
  import java.lang.annotation.ElementType;
  import java.lang.annotation.Inherited;
  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  import java.lang.annotation.Target;

  @Inherited
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.TYPE)
  @interface MyInheritedAnnotation {
  }

  @MyInheritedAnnotation
  class ParentClass {
  }

  class ChildClass extends ParentClass {
  }

  public class InheritedExample {
      public static void main(String[] args) {
          if (ChildClass.class.isAnnotationPresent(MyInheritedAnnotation.class)) {
              System.out.println("MyInheritedAnnotation is present in ChildClass");
          } else {
              System.out.println("MyInheritedAnnotation is not present in ChildClass");
          }
      }
  }
  • Explanation:
    In this example, MyInheritedAnnotation is defined as an @Inherited annotation. The ParentClass is annotated with @MyInheritedAnnotation, and when ChildClass extends ParentClass, it automatically inherits the annotation.

iii) @Retention:

  • Definition:
    The @Retention annotation specifies how long an annotation should be retained. It has three possible retention policies:
  • RetentionPolicy.SOURCE: Annotations are discarded by the compiler.
  • RetentionPolicy.CLASS: Annotations are recorded in the class file but not available at runtime.
  • RetentionPolicy.RUNTIME: Annotations are available at runtime.
  • Example:
  import java.lang.annotation.ElementType;
  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  import java.lang.annotation.Target;
  import java.lang.reflect.Method;

  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.METHOD)
  @interface MyRuntimeAnnotation {
      String value();
  }

  class MyClass {
      @MyRuntimeAnnotation(value = "This is a runtime annotation")
      public void myMethod() {
          System.out.println("My Method is called");
      }
  }

  public class RetentionExample {
      public static void main(String[] args) throws Exception {
          MyClass obj = new MyClass();
          Method method = obj.getClass().getMethod("myMethod");

          if (method.isAnnotationPresent(MyRuntimeAnnotation.class)) {
              MyRuntimeAnnotation annotation = method.getAnnotation(MyRuntimeAnnotation.class);
              System.out.println("Annotation value: " + annotation.value());
          }

          obj.myMethod();
      }
  }
  • Explanation:
    In this example, MyRuntimeAnnotation is defined with RetentionPolicy.RUNTIME, meaning it is available at runtime. The RetentionExample class retrieves the annotation value using reflection and prints it.

Summary:

  • @Override is used to ensure that a method is correctly overriding a superclass method.
  • @Inherited allows an annotation to be inherited by subclasses.
  • @Retention determines how long an annotation is retained (e.g., source, class, or runtime).

These annotations are powerful tools that help improve code quality and maintainability in Java.

Leave a Reply

Your email address will not be published. Required fields are marked *