简体   繁体   中英

@Nullable Eclipse Analysis not working properly

I find it quite handy to use the @Nullable and @Nonnull Annotations for Parameters and return values.

However the Eclipse Analysis seems a bit patchy. I find the follwing case to be really annoying:

public class SomeEntity {
  private SomeObj someObj;

  public void setSomeObj(@Nullable SomeObj someObj) {
    this.someObj = someObj;
  }

  @Nullable public SomeObj getSomeObj() {
    return someObj;
  }

  public boolean hasNewSomeObj() {
    return someObj != null;
  }
}

Now when I make the following call it gives me the following Eclipse warning as an error: "Potential null pointer access: The method getZuordnenMitDatenuebernahme() may return null"

if(someEntity.hasNewSomeObj()) {
  someOperator.doStuff(someEntity.getSomeObj().getSomething());
}

Even so the Null check is covered by the prior method call.

Does anyone have any good suggestions on how to deal with this? I would really like to keep my annotations on the return values.

Eclipse: Juno Release 1

Java: 1.6

jsr305 implementation: com.google.findbugs.jsr305 2.0.1

Actually @thr0wable provided a good answer.

It is not possible for the Eclipse compiler to guarantee, that someEntity.getSomeObj() will not return null after someEntity.hasNewSomeObj() was called, because multiple threads may access and modify someEntity at any time.

For the same reason the following code will also produce a compile time error for good reason:

if(someEntity.getSomeObj() != null) {
    someOperator.doStuff(someEntity.getSomeObj().getSomething());
}

The only way to guarantee, that the object is actually not null, is by doing the following:

SomeObj o = someEntity.getSomeObj();
if(o != null) {
    someOperator.doStuff(o.getSomething());
}

UPDATE

With Java 8, you should consider using Optional , which provides exactly the functionality you need:

static class SomeEntity {
    private Optional<Object> someObj;

    public void setSomeObj(Object someObj) {
        this.someObj = Optional.ofNullable(someObj);
    }

    public Optional<Object> getSomeObj() {
        return someObj;
    }
}

Then your example code could be simplified to this, when using a lambda expression:

someEntity.getSomeObj().ifPresent(o -> System.out.println(o));

I'm not sure, if the compile time checks are already implemented in the latest JDT Java 8 build, but once it gets released, I think you should certainly get compile time warnings/errors, if you try to access an Optional Object by Optional#get() without first checking Optional#isPresent() .

In

if(someEntity.hasNewSomeObj()) {
  someOperator.doStuff(someEntity.getSomeObj().getSomething());
}

The call to someEntity.getSomeObj() may still return null as you declare @Nullable , so calling getSomething() then will result in a NPE.

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