@Inherited
is a meta-annotation in Java used to indicate that an annotation type is automatically inherited by subclasses of annotated classes.
It is defined in the package: java.lang.annotation.Inherited
By default, annotations are not inherited by subclasses. The @Inherited
annotation allows custom annotations to be passed down from a superclass to its subclasses only if applied on the class level.
Why is @Inherited important?
- Enables annotation inheritance across class hierarchies.
- Useful in framework design (e.g., access control, configuration metadata, role-based security).
- Promotes reusability and consistency in code design.
Syntax
To use @Inherited
, annotate a custom annotation definition:
import java.lang.annotation.*;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Info {
String author();
}
Code language: CSS (css)
Simple Example
import java.lang.annotation.*; @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface DevelopedBy { String name(); } // Superclass @DevelopedBy(name = "LotusJavaPrince") class BaseService { } // Subclass class SubService extends BaseService { } public class InheritedExample { public static void main(String[] args) { Class<?> cls = SubService.class; DevelopedBy db = cls.getAnnotation(DevelopedBy.class); if (db != null) { System.out.println("SubService is developed by: " + db.name()); } else { System.out.println("Annotation not inherited."); } } }
Output:
SubService is developed by: LotusJavaPrince
Problem Statement:
Mahesh wants to define a security classification for banking services using annotations. LotusJavaPrince creates a @SecureLevel
annotation that should automatically apply to all subclasses of BankingService
. Using @Inherited
, Mahesh ensures that all services, even when extended, retain security metadata for audit and access control purposes.
import java.lang.annotation.*; // Step 1: Define Inheritable Annotation @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface SecureLevel { String value(); } // Step 2: Superclass with Annotation @SecureLevel("HIGH") class BankingService { public void processTransaction() { System.out.println("Processing transaction..."); } } // Step 3: Subclass (inherits annotation) class LoanService extends BankingService { public void approveLoan() { System.out.println("Loan approved."); } } // Step 4: Auditor Logic public class SecurityLevelAuditor { public static void main(String[] args) { Class<?> cls = LoanService.class; if (cls.isAnnotationPresent(SecureLevel.class)) { SecureLevel level = cls.getAnnotation(SecureLevel.class); System.out.println("Security Level of " + cls.getSimpleName() + ": " + level.value()); } else { System.out.println("No security level defined."); } } }
Output:
Security Level of LoanService: HIGH
The @Inherited
meta-annotation in Java is essential when you want annotation metadata to propagate automatically to subclasses. This is particularly useful in large-scale enterprise systems where consistent metadata (like logging levels, security roles, or configuration settings) must be retained across extended components.
While powerful, it has limitations and should be combined thoughtfully with reflection and other meta-annotations like @Target
and @Retention
to build flexible, annotation-driven applications.