0
# Annotation Generation
1
2
AutoAnnotation generates proper implementations of annotation interfaces with correct equals(), hashCode(), and toString() methods that conform to the Java annotation specification.
3
4
## Basic Annotation Generation
5
6
```java { .api }
7
// Annotation interface
8
public @interface Named {
9
String value();
10
}
11
12
// Factory method with @AutoAnnotation
13
public class Annotations {
14
@AutoAnnotation
15
public static Named named(String value) {
16
return new AutoAnnotation_Annotations_named(value);
17
}
18
}
19
```
20
21
## Usage Example
22
23
```java
24
Named annotation = Annotations.named("example");
25
System.out.println(annotation); // @Named(value="example")
26
System.out.println(annotation.value()); // "example"
27
28
// Proper equals() behavior
29
Named same = Annotations.named("example");
30
Named different = Annotations.named("other");
31
System.out.println(annotation.equals(same)); // true
32
System.out.println(annotation.equals(different)); // false
33
```
34
35
## Multi-Parameter Annotations
36
37
```java { .api }
38
// Complex annotation
39
public @interface ApiEndpoint {
40
String path();
41
String method() default "GET";
42
boolean authenticated() default true;
43
String[] produces() default {};
44
}
45
46
// Factory method
47
public class Annotations {
48
@AutoAnnotation
49
public static ApiEndpoint apiEndpoint(
50
String path,
51
String method,
52
boolean authenticated,
53
String[] produces) {
54
return new AutoAnnotation_Annotations_apiEndpoint(path, method, authenticated, produces);
55
}
56
}
57
```
58
59
Usage:
60
61
```java
62
ApiEndpoint endpoint = Annotations.apiEndpoint(
63
"/api/users",
64
"POST",
65
true,
66
new String[]{"application/json"});
67
68
System.out.println(endpoint.path()); // "/api/users"
69
System.out.println(endpoint.method()); // "POST"
70
System.out.println(endpoint.authenticated()); // true
71
System.out.println(Arrays.toString(endpoint.produces())); // ["application/json"]
72
```
73
74
## Annotations with Default Values
75
76
Factory methods can omit parameters that have default values:
77
78
```java { .api }
79
public @interface RequestMapping {
80
String path();
81
String method() default "GET";
82
int timeout() default 5000;
83
}
84
85
public class Annotations {
86
// Full parameter version
87
@AutoAnnotation
88
public static RequestMapping requestMapping(String path, String method, int timeout) {
89
return new AutoAnnotation_Annotations_requestMapping(path, method, timeout);
90
}
91
92
// Convenience method using defaults
93
@AutoAnnotation
94
public static RequestMapping requestMapping(String path) {
95
return new AutoAnnotation_Annotations_requestMapping(path, "GET", 5000);
96
}
97
98
// Partial defaults
99
@AutoAnnotation
100
public static RequestMapping requestMapping(String path, String method) {
101
return new AutoAnnotation_Annotations_requestMapping(path, method, 5000);
102
}
103
}
104
```
105
106
Usage:
107
108
```java
109
RequestMapping simple = Annotations.requestMapping("/api/data");
110
RequestMapping withMethod = Annotations.requestMapping("/api/data", "POST");
111
RequestMapping full = Annotations.requestMapping("/api/data", "POST", 10000);
112
```
113
114
## Array-Valued Annotations
115
116
AutoAnnotation properly handles array-valued annotation elements:
117
118
```java { .api }
119
public @interface Tags {
120
String[] value();
121
int[] priorities() default {};
122
}
123
124
public class Annotations {
125
@AutoAnnotation
126
public static Tags tags(String[] value, int[] priorities) {
127
return new AutoAnnotation_Annotations_tags(value, priorities);
128
}
129
130
// Convenience method for single tag
131
public static Tags tag(String tag) {
132
return tags(new String[]{tag}, new int[]{});
133
}
134
}
135
```
136
137
Usage:
138
139
```java
140
Tags multipleTags = Annotations.tags(
141
new String[]{"web", "api", "rest"},
142
new int[]{1, 2, 3});
143
144
Tags singleTag = Annotations.tag("important");
145
146
// Arrays are properly cloned for immutability
147
String[] originalArray = {"test"};
148
Tags tagsFromArray = Annotations.tags(originalArray, new int[]{});
149
originalArray[0] = "modified"; // Doesn't affect the annotation
150
System.out.println(tagsFromArray.value()[0]); // Still "test"
151
```
152
153
## Nested Annotation Types
154
155
AutoAnnotation works with annotations that contain other annotations:
156
157
```java { .api }
158
public @interface Validation {
159
String message();
160
int code();
161
}
162
163
public @interface Field {
164
String name();
165
Validation[] validations() default {};
166
}
167
168
public class Annotations {
169
@AutoAnnotation
170
public static Validation validation(String message, int code) {
171
return new AutoAnnotation_Annotations_validation(message, code);
172
}
173
174
@AutoAnnotation
175
public static Field field(String name, Validation[] validations) {
176
return new AutoAnnotation_Annotations_field(name, validations);
177
}
178
}
179
```
180
181
Usage:
182
183
```java
184
Validation required = Annotations.validation("Field is required", 1001);
185
Validation minLength = Annotations.validation("Minimum length is 3", 1002);
186
187
Field nameField = Annotations.field("username", new Validation[]{required, minLength});
188
```
189
190
## Enum-Valued Annotations
191
192
AutoAnnotation handles enum values correctly:
193
194
```java { .api }
195
public enum Priority {
196
LOW, MEDIUM, HIGH, CRITICAL
197
}
198
199
public @interface Task {
200
String description();
201
Priority priority() default Priority.MEDIUM;
202
}
203
204
public class Annotations {
205
@AutoAnnotation
206
public static Task task(String description, Priority priority) {
207
return new AutoAnnotation_Annotations_task(description, priority);
208
}
209
210
// Convenience method with default priority
211
public static Task task(String description) {
212
return task(description, Priority.MEDIUM);
213
}
214
}
215
```
216
217
Usage:
218
219
```java
220
Task normalTask = Annotations.task("Implement feature");
221
Task urgentTask = Annotations.task("Fix critical bug", Priority.CRITICAL);
222
```
223
224
## Class-Valued Annotations
225
226
AutoAnnotation supports Class<?> annotation elements:
227
228
```java { .api }
229
public @interface Converter {
230
Class<?> from();
231
Class<?> to();
232
Class<? extends TypeConverter> converter();
233
}
234
235
public class Annotations {
236
@AutoAnnotation
237
public static Converter converter(Class<?> from, Class<?> to, Class<? extends TypeConverter> converter) {
238
return new AutoAnnotation_Annotations_converter(from, to, converter);
239
}
240
}
241
```
242
243
Usage:
244
245
```java
246
Converter stringToInt = Annotations.converter(String.class, Integer.class, StringToIntConverter.class);
247
```
248
249
## Generic Factory Methods
250
251
Factory methods can be generic for flexibility:
252
253
```java { .api }
254
public @interface TypedAnnotation {
255
Class<?> value();
256
}
257
258
public class Annotations {
259
@AutoAnnotation
260
public static TypedAnnotation typedAnnotation(Class<?> value) {
261
return new AutoAnnotation_Annotations_typedAnnotation(value);
262
}
263
264
// Generic convenience method
265
public static <T> TypedAnnotation typedAnnotation(Class<T> type) {
266
return typedAnnotation((Class<?>) type);
267
}
268
}
269
```
270
271
## Private Factory Methods
272
273
AutoAnnotation methods can have any visibility:
274
275
```java { .api }
276
public class InternalAnnotations {
277
@AutoAnnotation
278
private static Internal internal(String value) {
279
return new AutoAnnotation_InternalAnnotations_internal(value);
280
}
281
282
// Public wrapper method
283
public static Internal createInternal(String value) {
284
validateInternalValue(value);
285
return internal(value);
286
}
287
288
private static void validateInternalValue(String value) {
289
if (value.isEmpty()) {
290
throw new IllegalArgumentException("Internal value cannot be empty");
291
}
292
}
293
}
294
```
295
296
## Integration with Builders
297
298
Combine AutoAnnotation with AutoBuilder for fluent annotation creation:
299
300
```java { .api }
301
public @interface Configuration {
302
String name();
303
String value();
304
boolean required() default false;
305
String description() default "";
306
}
307
308
public class Annotations {
309
@AutoAnnotation
310
public static Configuration configuration(String name, String value, boolean required, String description) {
311
return new AutoAnnotation_Annotations_configuration(name, value, required, description);
312
}
313
}
314
315
@AutoBuilder(callMethod = "configuration", ofClass = Annotations.class)
316
public abstract class ConfigurationBuilder {
317
public static ConfigurationBuilder builder() {
318
return new AutoBuilder_ConfigurationBuilder()
319
.setRequired(false)
320
.setDescription("");
321
}
322
323
public abstract ConfigurationBuilder setName(String name);
324
public abstract ConfigurationBuilder setValue(String value);
325
public abstract ConfigurationBuilder setRequired(boolean required);
326
public abstract ConfigurationBuilder setDescription(String description);
327
public abstract Configuration build();
328
}
329
```
330
331
Usage:
332
333
```java
334
Configuration config = ConfigurationBuilder.builder()
335
.setName("database.url")
336
.setValue("jdbc:postgresql://localhost:5432/mydb")
337
.setRequired(true)
338
.setDescription("Database connection URL")
339
.build();
340
```
341
342
## Null Handling
343
344
AutoAnnotation validates non-null parameters:
345
346
```java { .api }
347
public @interface Description {
348
String value();
349
String author();
350
}
351
352
public class Annotations {
353
@AutoAnnotation
354
public static Description description(String value, String author) {
355
return new AutoAnnotation_Annotations_description(value, author);
356
}
357
}
358
```
359
360
```java
361
// This will throw NullPointerException
362
Description desc = Annotations.description(null, "Alice"); // NPE: value cannot be null
363
Description desc2 = Annotations.description("text", null); // NPE: author cannot be null
364
```
365
366
## Performance Characteristics
367
368
- Generated annotation implementations use efficient equals() and hashCode()
369
- Array parameters are cloned to ensure immutability
370
- No reflection is used at runtime
371
- toString() provides standard annotation string format
372
- Generated classes are optimized for the specific annotation interface