How
Java annotations
work
@Entity
@Data
public class User {
@Id
private Long id;
@NotNull
@Valid
private String name;
@Autowired
private Service service;
@Override
public String toString() {
return "User: " + name;
}
}
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value();
}
int
, long
,
double
, etc)String
, Class
, Enum
Must be CONSTANT
public @interface MyAnnotation {
String value();
int count() default 0;
}
✅ @MyAnnotation("x")
✅ @MyAnnotation(value = "x")
✅ @MyAnnotation(value = "x", count = 42)
⛔ @MyAnnotation("x", count = 42)
⛔ @MyAnnotation(count = 42)
@Target |
🟢 |
@Retention |
🟢 |
@Documented |
⭕ |
@Repeatable |
⭕ |
@Inherited |
⭕ |
@Documented |
put it in Javadoc |
@Repeatable |
use it multiple times |
@Inherited |
also put it on subclasses |
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
Available through reflection
@MyAnnotation("woohoo")
public class MyClass {}
Class<?> myClass = MyClass.class;
Annotation[] annotations = myClass.getDeclaredAnnotations();
// Annotation[1] = { MyAnnotation("woohoo") }
MyAnnotation ann = myClass.getAnnotation(MyAnnotation.class);
// MyAnnotation("woohoo")
ann.value()
// "woohoo"
public class MyClass {
@MyAnnotation("wheee")
public String myField;
}
Class<?> myClass = MyClass.class;
Field field = myClass.getField("myField");
Annotation[] annotations = field.getDeclaredAnnotations();
// Annotation[1] = { MyAnnotation("wheee") }
MyAnnotation ann = field.getAnnotation(MyAnnotation.class);
// MyAnnotation("wheee")
ann.value()
// "wheee"
@Retention(RetentionPolicy.CLASS)
Written into classfile but unavailable
@Retention(RetentionPolicy.SOURCE)
Available only at compile-time
Annotations are like magic
Jan Ouwens
│ EqualsVerifier │ jqno.nl │ jqno
Slides at jqno.nl/talks