uber/NullAway

Document sources of deliberate unsoundness

Geschlossen

#1.617 geöffnet am 20.06.2026

 (5 Kommentare) (0 Reaktionen) (1 zugewiesene Person)Java (288 Forks)batch import
documentationgood first issue

Repository-Metriken

Stars
 (3.462 Sterne)
PR-Merge-Metriken
 (Durchschn. Merge 3T 23h) (14 gemergte PRs in 30 T)

Beschreibung

Description

NullAway currently does not warn when doing nested null-checks with mutable data. I can write:

if(rental.returnPolicy() == null || rental.returnPolicy().mustBeReturnedAfter() == null){
    //                                                                                   ^^^^^
    // is not, but should be: [NullAway] dereferenced expression rental.returnPolicy() is @Nullable
    // returnPolicy is just a method so its return value could change between first and second call
    return 0;
}

To me that seems like a false negative. It does not warn but should.

Minimal repro

import org.jetbrains.annotations.Nullable;

public class Main {
    public static void main(String[] args){
        check(new RegularRental());
    }

    static int check(Rental rental){
        if(rental.returnPolicy() == null || rental.returnPolicy().mustBeReturnedAfter() == null){
            //                                                    ^^^^^^^^^^^^^^^^^^^^
            // is not, but should be: [NullAway] dereferenced expression rental.returnPolicy() is @Nullable
            // returnPolicy is just a method so its return value could change between first and second call
            return 0;
        }
        return 1;
    }
}


interface Rental {
    @Nullable ReturnPolicy returnPolicy();
}

class RegularRental implements Rental {

    private ReturnPolicy returnPolicy = new ReturnPolicy("2");

    @Override public ReturnPolicy returnPolicy(){ return this.returnPolicy; }
}

class ReturnPolicy {
    private @Nullable String mustBeReturnedAfter;

    ReturnPolicy(@Nullable String mustBeReturnedAfter) { this.mustBeReturnedAfter = mustBeReturnedAfter; }

    public @Nullable String mustBeReturnedAfter() { return mustBeReturnedAfter; }
}

Contributor Guide