How to indicate that member fields are @Nonnull by default?

6.8k views Asked by At

My question is a follow-up to this one.

In past versions of FindBugs, it was possible to use @DefaultAnnotation(Nonnull.class) or @DefaultAnnotationForFields(Nonnull.class) to indicate that all fields in a package should be treated as @Nonnull. In the current version of FindBugs (2.0), @DefaultAnnotation and @DefaultAnnotationForFields are deprecated, and we should all use JSR-305 instead. But JSR-305 doesn't seem to cover everything the (now deprecated) FindBugs annotations cover.

The javadoc does suggest a number of alternatives:

  • @ParametersAreNonnullByDefault. This (obviously) only applies to parameters, not to member fields.
  • @CheckReturnValue, when applied to a type or package. Again, this doesn't apply to member fields.
  • @TypeQualifierDefault. Maybe this can do what I want, but I don't understand how it works, and I'm unable to find any documentation or examples on its usage or intent, besides some cryptic javadoc. I think it will help me create my own annotations, but can I be sure that all the tools (FindBugs, Eclipse, etc.) will interpret this new annotation correctly (or even at all)?

The javadoc doesn't provide any hints on how to deal with its deprecation.

So, using the current versions of FindBugs and/or JSR-305, how should I indicate that all member fields in a certain package (or even in a certain class) are supposed to be treated as @Nonnull? Is it even possible?

1

There are 1 answers

3
Mat Grainger On BEST ANSWER

I had a similar question, and found that the following seems to work with findbugs (2.0.1-rc2)

Create a java file with the following annotation definition

@Nonnull
@TypeQualifierDefault(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldsAreNonNullByDefault
{
}

similarly, to enforce that all return values from a method are non-null

@Nonnull
@TypeQualifierDefault(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ReturnTypesAreNonNullByDefault
{
}

and then annotate the package as normal.

I used the following for my tests (package-info.java)

@javax.annotation.ParametersAreNonnullByDefault
@com.habit.lib.lang.FieldsAreNonNullByDefault
@com.habit.lib.lang.ReturnTypesAreNonNullByDefault

package com.mypackagename.subpkg;