0
# Default Annotations
1
2
Apply annotations by default to all members of a class or package, reducing annotation verbosity while maintaining safety. These annotations are particularly useful for establishing consistent nullability policies or other behavioral constraints across entire codebases.
3
4
## Capabilities
5
6
### DefaultAnnotation
7
8
Apply specified annotations to all members of a class or package by default.
9
10
```java { .api }
11
/**
12
* Indicates that all members of the class or package should be annotated with
13
* the default value of the supplied annotation class.
14
*
15
* This would be used for behavior annotations such as @NonNull, @CheckForNull,
16
* or @CheckReturnValue.
17
*
18
* In particular, you can use @DefaultAnnotation(NonNull.class) on a class or
19
* package, and then use @Nullable only on those parameters, methods or fields
20
* that you want to allow to be null.
21
*/
22
@Documented
23
@Target({ ElementType.TYPE, ElementType.PACKAGE })
24
@Retention(RetentionPolicy.CLASS)
25
@interface DefaultAnnotation {
26
Class<? extends Annotation>[] value();
27
28
@Deprecated
29
Priority priority() default Priority.MEDIUM;
30
31
Confidence confidence() default Confidence.MEDIUM;
32
}
33
```
34
35
**Usage Examples:**
36
37
```java
38
// Apply @NonNull by default to all class members
39
@DefaultAnnotation(NonNull.class)
40
public class UserService {
41
42
// Implicitly @NonNull - no annotation needed
43
private UserRepository repository;
44
45
// Implicitly @NonNull parameters and return value
46
public String getUserName(String userId) {
47
return repository.findNameById(userId);
48
}
49
50
// Explicit @Nullable overrides the default
51
@Nullable
52
public User findUser(String userId) {
53
return repository.findById(userId); // May return null
54
}
55
56
// Implicitly @NonNull parameter
57
public void updateUser(User user) {
58
repository.save(user);
59
}
60
}
61
62
// Multiple default annotations
63
@DefaultAnnotation({NonNull.class, CheckReturnValue.class})
64
public class SecurityService {
65
66
// Both @NonNull and @CheckReturnValue applied by default
67
public boolean authenticate(String username, String password) {
68
return authProvider.validate(username, password);
69
}
70
71
// Override with @Nullable, but @CheckReturnValue still applies
72
@Nullable
73
public User getCurrentUser() {
74
return session.getUser(); // Return value should still be checked
75
}
76
}
77
78
// Package-level default annotation in package-info.java
79
@DefaultAnnotation(NonNull.class)
80
package com.example.service;
81
82
import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
83
import edu.umd.cs.findbugs.annotations.NonNull;
84
```
85
86
### DefaultAnnotationForFields
87
88
Apply specified annotations to all fields in a class or package by default.
89
90
```java { .api }
91
/**
92
* Indicates that all fields of the class or package should be annotated with
93
* the default value of the supplied annotation class.
94
*/
95
@Documented
96
@Target({ ElementType.TYPE, ElementType.PACKAGE })
97
@Retention(RetentionPolicy.CLASS)
98
@interface DefaultAnnotationForFields {
99
Class<? extends Annotation>[] value();
100
101
@Deprecated
102
Priority priority() default Priority.MEDIUM;
103
104
Confidence confidence() default Confidence.MEDIUM;
105
}
106
```
107
108
**Usage Examples:**
109
110
```java
111
// All fields are @NonNull by default
112
@DefaultAnnotationForFields(NonNull.class)
113
public class UserData {
114
115
// Implicitly @NonNull
116
private String username;
117
private String email;
118
private Date createdAt;
119
120
// Explicit @Nullable overrides default
121
@Nullable
122
private String displayName;
123
124
// Constructor can assume non-null fields
125
public UserData(String username, String email) {
126
this.username = username; // Safe - implicitly @NonNull
127
this.email = email; // Safe - implicitly @NonNull
128
this.createdAt = new Date();
129
}
130
}
131
```
132
133
### DefaultAnnotationForMethods
134
135
Apply specified annotations to all methods in a class or package by default.
136
137
```java { .api }
138
/**
139
* Indicates that all methods of the class or package should be annotated with
140
* the default value of the supplied annotation class.
141
*/
142
@Documented
143
@Target({ ElementType.TYPE, ElementType.PACKAGE })
144
@Retention(RetentionPolicy.CLASS)
145
@interface DefaultAnnotationForMethods {
146
Class<? extends Annotation>[] value();
147
148
@Deprecated
149
Priority priority() default Priority.MEDIUM;
150
151
Confidence confidence() default Confidence.MEDIUM;
152
}
153
```
154
155
**Usage Examples:**
156
157
```java
158
// All methods should have their return values checked
159
@DefaultAnnotationForMethods(CheckReturnValue.class)
160
public class FileOperations {
161
162
// Return value should be checked (implicit @CheckReturnValue)
163
public boolean createFile(String filename) {
164
try {
165
return new File(filename).createNewFile();
166
} catch (IOException e) {
167
return false;
168
}
169
}
170
171
// Return value should be checked (implicit @CheckReturnValue)
172
public boolean deleteFile(String filename) {
173
return new File(filename).delete();
174
}
175
176
// Void methods not affected by @CheckReturnValue
177
public void logOperation(String operation) {
178
logger.info("File operation: " + operation);
179
}
180
}
181
182
// Multiple annotations for methods
183
@DefaultAnnotationForMethods({CheckReturnValue.class, NonNull.class})
184
public class ValidationService {
185
186
// Both @CheckReturnValue and @NonNull (for return value) applied
187
public ValidationResult validate(String input) {
188
return validator.validate(input);
189
}
190
191
// Override with @Nullable return value
192
@Nullable
193
public String normalize(String input) {
194
return input != null ? input.trim() : null;
195
}
196
}
197
```
198
199
### DefaultAnnotationForParameters
200
201
Apply specified annotations to all parameters in a class or package by default.
202
203
```java { .api }
204
/**
205
* Indicates that all parameters of methods in the class or package should be annotated with
206
* the default value of the supplied annotation class.
207
*/
208
@Documented
209
@Target({ ElementType.TYPE, ElementType.PACKAGE })
210
@Retention(RetentionPolicy.CLASS)
211
@interface DefaultAnnotationForParameters {
212
Class<? extends Annotation>[] value();
213
214
@Deprecated
215
Priority priority() default Priority.MEDIUM;
216
217
Confidence confidence() default Confidence.MEDIUM;
218
}
219
```
220
221
**Usage Examples:**
222
223
```java
224
// All parameters are @NonNull by default
225
@DefaultAnnotationForParameters(NonNull.class)
226
public class StringUtils {
227
228
// Both parameters are implicitly @NonNull
229
public String concatenate(String first, String second) {
230
return first + second; // Safe - no null checks needed
231
}
232
233
// All parameters implicitly @NonNull
234
public String format(String template, Object... args) {
235
return MessageFormat.format(template, args);
236
}
237
238
// Explicit @Nullable overrides default
239
public String withDefault(@Nullable String input, String defaultValue) {
240
return input != null ? input : defaultValue;
241
}
242
}
243
```
244
245
### ReturnValuesAreNonnullByDefault
246
247
Specialized default annotation indicating that method return values are non-null by default.
248
249
```java { .api }
250
/**
251
* This annotation can be applied to a package, class or method to indicate that
252
* the methods in that element have nonnull return values by default unless
253
* there is:
254
* - An explicit nullness annotation
255
* - The method overrides a method in a superclass (in which case the
256
* annotation of the corresponding parameter in the superclass applies)
257
* - there is a default annotation applied to a more tightly nested element.
258
*/
259
@Documented
260
@Nonnull
261
@TypeQualifierDefault(ElementType.METHOD)
262
@Retention(RetentionPolicy.RUNTIME)
263
@interface ReturnValuesAreNonnullByDefault {
264
}
265
```
266
267
**Usage Examples:**
268
269
```java
270
// All method return values are non-null by default
271
@ReturnValuesAreNonnullByDefault
272
public class DataService {
273
274
// Returns non-null value (implicit @NonNull)
275
public List<User> getAllUsers() {
276
List<User> users = repository.findAll();
277
return users != null ? users : Collections.emptyList();
278
}
279
280
// Returns non-null value (implicit @NonNull)
281
public String getUserName(String userId) {
282
String name = repository.findNameById(userId);
283
return name != null ? name : "Unknown";
284
}
285
286
// Explicit @Nullable overrides the default
287
@Nullable
288
public User findUser(String userId) {
289
return repository.findById(userId); // May return null
290
}
291
}
292
293
// Package-level application in package-info.java
294
@ReturnValuesAreNonnullByDefault
295
package com.example.data;
296
297
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;
298
```
299
300
## Combining Default Annotations
301
302
Default annotations can be combined for comprehensive coverage:
303
304
```java
305
// Comprehensive default annotations
306
@DefaultAnnotationForParameters(NonNull.class) // All parameters non-null
307
@DefaultAnnotationForMethods(CheckReturnValue.class) // All returns should be checked
308
@ReturnValuesAreNonnullByDefault // All returns are non-null
309
public class RobustService {
310
311
// Parameters implicitly @NonNull, return implicitly @NonNull and @CheckReturnValue
312
public boolean processData(String input, ProcessOptions options) {
313
try {
314
processor.process(input, options);
315
return true;
316
} catch (ProcessException e) {
317
logger.error("Processing failed", e);
318
return false;
319
}
320
}
321
322
// Override defaults as needed
323
public void logMessage(@Nullable String message) { // Override parameter default
324
if (message != null) {
325
logger.info(message);
326
}
327
}
328
}
329
```
330
331
## Package-Level Defaults
332
333
Apply default annotations to entire packages using `package-info.java`:
334
335
```java
336
/**
337
* Package with comprehensive null safety defaults.
338
*
339
* All parameters and return values are non-null by default unless explicitly
340
* annotated otherwise. All method return values should be checked.
341
*/
342
@DefaultAnnotation({NonNull.class, CheckReturnValue.class})
343
@ReturnValuesAreNonnullByDefault
344
package com.example.secure;
345
346
import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
347
import edu.umd.cs.findbugs.annotations.NonNull;
348
import edu.umd.cs.findbugs.annotations.CheckReturnValue;
349
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;
350
```
351
352
## Best Practices
353
354
1. **Start with packages**: Apply default annotations at the package level for consistency
355
2. **Use specific defaults**: Choose different defaults for different scopes (fields vs parameters vs methods)
356
3. **Document overrides**: Clearly document when and why you override defaults
357
4. **Gradual adoption**: Start with new code and gradually apply to existing code
358
5. **Team consistency**: Establish team conventions for which defaults to use
359
6. **Tool integration**: Ensure your build tools and IDEs understand the default annotations
360
7. **Override judiciously**: Only override defaults when necessary - too many overrides defeat the purpose