Annotations provide metadata about the program and can be used for various purposes, such as configuration and documentation. Understanding how to create and use annotations is essential for modern Java development.
To explore Java annotations in detail, refer to our article: Java Annotations.
An annotation is a form of metadata that provides data about a program but is not part of the program itself.
You define an annotation using the @interface
keyword.
public @interface MyAnnotation {
String value();
}
Some built-in annotations include @Override
, @Deprecated
, and @SuppressWarnings
.
@Override
annotation?The @Override
annotation indicates that a method is intended to override a method in a superclass.
class Parent {
void display() {}
}
class Child extends Parent {
@Override
void display() {} // Correctly overrides
}
@Deprecated
annotation?The @Deprecated
annotation indicates that a method or class is outdated and should not be used.
@Deprecated
void oldMethod() {}
@SuppressWarnings
annotation?The @SuppressWarnings
annotation is used to suppress compiler warnings for the annotated element.
@SuppressWarnings("unchecked")
List<String> list = new ArrayList();
You can apply an annotation to a method by placing it above the method declaration.
@MyAnnotation("Example")
void myMethod() {}
Yes, annotations can have parameters, which are defined as methods in the annotation interface.
public @interface MyAnnotation {
String value();
int count() default 1; // Default value
}
A marker annotation is an annotation that does not have any elements and is used to mark a class or method.
public @interface MyMarkerAnnotation {}
A single-value annotation is an annotation that has only one element, allowing you to use a shorthand syntax.
public @interface MySingleValue {
String value();
}
@MySingleValue("Example") // Shorthand
void myMethod() {}
A repeatable annotation allows you to apply the same annotation multiple times to a single element.
@Repeatable(MyAnnotations.class)
public @interface MyAnnotation {
String value();
}
You create a repeatable annotation by using the @Repeatable
meta-annotation.
@Repeatable(MyAnnotations.class)
public @interface MyAnnotation {
String value();
}
A meta-annotation is an annotation that is applied to another annotation, such as @Retention
or @Target
.
@Retention
annotation?The @Retention
annotation specifies how long annotations with the annotated type are to be retained.
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
The retention policies are SOURCE
, CLASS
, and RUNTIME
.
@Target
annotation?The @Target
annotation specifies the kinds of program elements to which an annotation type is applicable.
@Target(ElementType.METHOD)
public @interface MyAnnotation {}
@Target
?The element types include TYPE
, FIELD
, METHOD
, PARAMETER
, CONSTRUCTOR
, LOCAL_VARIABLE
, ANNOTATION_TYPE
, PACKAGE
.
@Inherited
annotation?The @Inherited
annotation indicates that an annotation type is automatically inherited.
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyInheritedAnnotation {}
You can access annotations at runtime using reflection.
MyAnnotation annotation = MyClass.class.getAnnotation(MyAnnotation.class);
getAnnotations()
method?The getAnnotations()
method returns all annotations present on a class, method, or field.
Annotation[] annotations = MyClass.class.getAnnotations();
isAnnotationPresent()
method?The isAnnotationPresent()
method checks if a specific annotation is present on a class, method, or field.
boolean isPresent = MyClass.class.isAnnotationPresent(MyAnnotation.class);
You can retrieve an annotation's value by calling the appropriate method on the annotation instance.
String value = annotation.value();
Documented
annotation?The Documented
annotation indicates that an annotation type is to be documented by the Javadoc tool.
RetentionPolicy
enum?The RetentionPolicy
enum defines the three retention policies: SOURCE
, CLASS
, and RUNTIME
.
You create a custom annotation by defining an interface with the @interface
keyword and specifying its properties.
public @interface MyCustomAnnotation {
String name();
int value();
}
Yes, annotations can be inherited if they are marked with the @Inherited
meta-annotation.
@FunctionalInterface
annotation?The @FunctionalInterface
annotation indicates that an interface is intended to be a functional interface, which has exactly one abstract method.
@FunctionalInterface
public interface MyFunctionalInterface {
void execute();
}
@Target(ElementType.TYPE)
and @Target(ElementType.METHOD)
?@Target(ElementType.TYPE)
indicates that the annotation can be applied to classes, interfaces, or enums, while @Target(ElementType.METHOD)
indicates it can only be applied to methods.
In Spring, annotations are used for configuration, such as @Component
, @Autowired
, and @RequestMapping
.
@Entity
annotation in JPA?The @Entity
annotation specifies that a class is an entity and is mapped to a database table.
@Entity
public class User {
@Id
private Long id;
private String name;
}
@Table
annotation in JPA?The @Table
annotation specifies the table to which an entity is mapped.
@Entity
@Table(name = "users")
public class User {}
@Column
annotation in JPA?The @Column
annotation specifies the column in the database table that is mapped to a field in the entity.
@Column(name = "user_name")
private String name;
@Id
annotation in JPA?The @Id
annotation specifies the primary key of an entity.
@Id
private Long id;
@GeneratedValue
annotation in JPA?The @GeneratedValue
annotation specifies that the value of the primary key will be generated automatically.
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany
annotation in JPA?The @OneToMany
annotation defines a one-to-many relationship between two entities.
@OneToMany(mappedBy = "user")
private List<Order> orders;
@ManyToOne
annotation in JPA?The @ManyToOne
annotation defines a many-to-one relationship between two entities.
@ManyToOne
private User user;
@ManyToMany
annotation in JPA?The @ManyToMany
annotation defines a many-to-many relationship between two entities.
@ManyToMany
private List<Tag> tags;
@Transactional
annotation in Spring?The @Transactional
annotation is used to define the scope of a transaction in Spring.
@Transactional
public void saveUser(User user) {}
@RequestMapping
annotation in Spring?The @RequestMapping
annotation is used to map web requests to specific handler methods in a controller.
@RequestMapping("/users")
public String getUsers() {}
@Autowired
annotation in Spring?The @Autowired
annotation is used for automatic dependency injection in Spring.
@Autowired
private UserService userService;
@Component
annotation in Spring?The @Component
annotation indicates that a class is a Spring component and should be managed by the Spring container.
@Component
public class UserService {}
@Service
annotation in Spring?The @Service
annotation is a specialization of the @Component
annotation, indicating that a class provides business services.
@Service
public class UserService {}
@Repository
annotation in Spring?The @Repository
annotation is a specialization of the @Component
annotation, indicating that a class is a data access object (DAO).
@Repository
public class UserRepository {}
@Configuration
annotation in Spring?The @Configuration
annotation indicates that a class declares one or more @Bean
methods and can be processed by the Spring container.
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
@Bean
annotation in Spring?The @Bean
annotation indicates that a method produces a bean to be managed by the Spring container.
@Bean
public UserService userService() {
return new UserService();
}
@Value
annotation in Spring?The @Value
annotation is used to inject values into fields from property files or environment variables.
@Value("${app.name}")
private String appName;
@PostConstruct
annotation?The @PostConstruct
annotation is used to indicate a method that should be executed after dependency injection is complete.
@PostConstruct
public void init() {
// initialization code
}
@PreDestroy
annotation?The @PreDestroy
annotation is used to indicate a method that should be executed just before the bean is removed from the context.
@PreDestroy
public void cleanup() {
// cleanup code
}
You create a custom annotation by defining an interface with the @interface
keyword and specifying its properties.
public @interface MyCustomAnnotation {
String value();
}
In JUnit, annotations like @Test
, @Before
, and @After
are used to define test methods and setup/teardown methods.
import org.junit.Test;
import org.junit.Before;
public class MyTest {
@Before
public void setUp() {
// setup code
}
@Test
public void testMethod() {
// test code
}
}