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, thedisplay()
method in theChild
class overrides thedisplay()
method in theParent
class. The@Override
annotation ensures that if the method signature in theChild
class does not match the one in theParent
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. TheParentClass
is annotated with@MyInheritedAnnotation
, and whenChildClass
extendsParentClass
, 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 withRetentionPolicy.RUNTIME
, meaning it is available at runtime. TheRetentionExample
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.