uber/NullAway

Document sources of deliberate unsoundness

Fechada

#1.617 aberto em 20 de jun. de 2026

 (5 comentários) (0 reação) (1 responsável)Java (288 forks)batch import
documentationgood first issue

Métricas do repositório

Stars
 (3.462 estrelas)
Métricas de merge de PR
 (Mesclagem média 3d 23h) (14 fundiu PRs em 30d)

Description

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; }
}

Guia do colaborador