简体   繁体   中英

@NonNullByDefault and @Nullable Evaluation in Eclipse

I am using the eclipse null annotations to check for possible NPE in my code.

Every class in my project has the @NonNullByDefault annotation. There are some fields that have the @Nullable annotation.

Here the problematic code:

@NonNullByDefault
public class MyClass{
    @Nullable
    private File myFile;

    public MyClass() {
        ...
        // Somewhere here myFile may or may not be initialised
        ...
        myMethod();
    }

    public void myMethod() {
        ...
        if( myFile != null ) {
            //AnotherClass also has @NonNullByDefault on it
            AnotherClass.callStaticFunction( myFile );
        }
    }
}

This code now gives me the error message:

Null type mismatch (type annotations): required '@NonNull File' but this expression has type '@Nullable File'

and will not compile.

When I change my method to:

public void myMethod() {
    ...
    File another = myFile;
    if( another != null ) {
        AnotherClass.callStaticFunction( another );
    }
}

the code will compile without any complaints.

Why is that so?

The online documentation contains a paragraph "The case of fields" which details the intricacies involved with accessing fields. Essentially, flow analysis can only make exact statements about variables which are owned by the current scope. Local variables are owned by the block in which they are declared, fields are not owned by any lexical scope, and hence are prone to unexpected effects due to any of

  • effects via aliased references
  • side effects of another method
  • concurrency

The same help text also outlines the two possible solutions (short of introducing more annotations, eg, to specify ownership):

  • assignment to a local variable before processing
  • "syntactic analysis", which recognizes a limited set of patterns that under normal conditions are sufficiently safe (without given full guarantees in this case).

The first of these strategies should normally be preferred and that's also what is mentioned in the question - so you should be fine.

Finally, I should mention there exists an RFE to introduce an annotation like @LazyNonNull , which would basically signal the following:

  • It is not necessary to initialize such fields in all constructors.
    • Hence, the field can possibly be null .
  • It is not possible to assign null to such a field.
    • Hence a null check against the field is sufficient for assuming non-null after the check.

More comments expressing demand in this directions may help motivating investments towards such a solution.

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