15. Annotations
15.1. Marker
1import java.lang.annotation.Retention;
2import java.lang.annotation.RetentionPolicy;
1@Retention(RetentionPolicy.RUNTIME)
2@interface OneOffCoder { }
3
4@OneOffCoder
5public static class Car {
6 private final String make, model;
7 private final int year;
8
9 public Car(String make, String model, int year) {
10 this.make = make;
11 this.model = model;
12 this.year = year;
13 }
14
15 @OneOffCoder
16 @Override
17 public String toString() {
18 return (new StringBuilder())
19 .append(make)
20 .append(' ')
21 .append(model)
22 .append(' ')
23 .append(year)
24 .toString();
25 }
26}
15.2. With fields
1import java.lang.annotation.Retention;
2import java.lang.annotation.RetentionPolicy;
3import java.lang.reflect.Method;
1@Retention(RetentionPolicy.RUNTIME)
2@interface Author {
3 String name() default "No One";
4 String org() default "FooBar, LLC";
5}
6
7@Author(name = "John Doe", org = "One-Off Coder")
8public static class Car {
9 private final String make, model;
10 private final int year;
11
12 public Car(String make, String model, int year) {
13 this.make = make;
14 this.model = model;
15 this.year = year;
16 }
17
18 @Author(name = "Jane Smith", org = "One-Off Coder")
19 @Override
20 public String toString() {
21 return (new StringBuilder())
22 .append(make)
23 .append(' ')
24 .append(model)
25 .append(' ')
26 .append(year)
27 .toString();
28 }
29}
1var car = new Car("Honda", "Accord", 2019);
2
3Class<?> clazz = car.getClass();
4var clazzAuthor = clazz.getAnnotation(Author.class);
5
6System.out.println(clazzAuthor.name() + " from " + clazzAuthor.org());
7
8Method method = clazz.getMethod("toString");
9var methodAuthor = method.getAnnotation(Author.class);
10
11System.out.println(methodAuthor.name() + " from " + methodAuthor.org());
15.3. Target
1import java.lang.annotation.ElementType;
2import java.lang.annotation.Retention;
3import java.lang.annotation.RetentionPolicy;
4import java.lang.annotation.Target;
1@Retention(RetentionPolicy.RUNTIME)
2@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
3@interface NeedsWork {}
4
5
6public static class Car {
7 private final String make, model;
8 private final int year;
9
10 @NeedsWork
11 public Car(String make, String model, int year) {
12 this.make = make;
13 this.model = model;
14 this.year = year;
15 }
16
17 @NeedsWork
18 @Override
19 public String toString() {
20 return (new StringBuilder())
21 .append(make)
22 .append(' ')
23 .append(model)
24 .append(' ')
25 .append(year)
26 .toString();
27 }
28}
15.4. Repeatable
1import java.lang.annotation.Retention;
2import java.lang.annotation.RetentionPolicy;
1@Retention(RetentionPolicy.RUNTIME)
2@java.lang.annotation.Repeatable(TodoRepeat.class)
3@interface Todo {
4 String description();
5}
6
7@Retention(RetentionPolicy.RUNTIME)
8@interface TodoRepeat {
9 Todo[] value();
10}
11
12public static class Car {
13 private final String make, model;
14 private final int year;
15
16 public Car(String make, String model, int year) {
17 this.make = make;
18 this.model = model;
19 this.year = year;
20 }
21
22 @Todo(description = "use regular string concatenation?")
23 @Todo(description = "unit test?")
24 @Override
25 public String toString() {
26 return (new StringBuilder())
27 .append(make)
28 .append(' ')
29 .append(model)
30 .append(' ')
31 .append(year)
32 .toString();
33 }
34}