简体   繁体   中英

Custom annotation to suppress a specific FindBugs warning

I want to create custom annotations to suppress individual FindBugs warnings to make it easier to use them via code-completion. For example, this one ignores constructors that don't set all @Nonnull fields.

@TypeQualifierDefault(ElementType.CONSTRUCTOR)
@SuppressFBWarnings("NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
@Retention(RetentionPolicy.CLASS)
public @interface SuppressNonnullFieldNotInitializedWarning
{ }

However, I still see the warning when using the annotation.

public class User {
    @Nonnull
    private String name;

    @SuppressNonnullFieldNotInitializedWarning
    public User() {
        // "Nonnull field name is not initialized by new User()"
    }
}

I've tried different retention policies and element types, putting the annotation on the constructor and the class, and even @TypeQualifierNickname .

This same pattern works to apply @Nonnull to all fields in a class.

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

FindBugs correctly displays a warning for code that assigns null to name .

@FieldsAreNonnullByDefault
public class User {
    private String name;

    public UserModel() {
        name = null;
        // "Store of null value into field User.name annotated Nonnull"
    }
}

I believe the problem is that @SuppressFBWarnings is not marked with @TypeQualifier while @Nonnull is, and thus @TypeQualifierDefault and @TypeQualifierNickname don't apply to it. But there must be some other mechanism to apply one annotation using another.

(Not specifically answering the question), but if you just want to make code-completion work better with @SuppressFBWarnings , you could define a static final String for each of the warning codes and then use those in the annotation. eg

public final class FBWarningCodes {
    private FBWarningCodes() { }

    public static final String NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR = "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR";
}

Then:

import static com.tmobile.tmo.cms.service.content.FBWarningCodes.*;

@SuppressFBWarnings(NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR)

(though admittedly Eclipse doesn't want to do code-completion unless you specify value= in the annotation)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM