@Nullable Eclipse Analysis не работает должным образом

1

Мне очень удобно использовать @Nullable и @Nonnull Annotations for Parameters и возвращать значения.

Однако анализ Eclipse выглядит несколько неоднородным. Я считаю, что дело в том, что это действительно раздражает:

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

Теперь, когда я делаю следующий вызов, он дает мне следующее предупреждение Eclipse как ошибку: "Потенциальный доступ к нулевому указателю: метод getZuordnenMitDatenuebernahme() может возвращать null"

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

Тем не менее проверка Null покрывается вызовом предыдущего метода.

Есть ли у кого-нибудь хорошие предложения о том, как с этим бороться? Я бы очень хотел, чтобы мои аннотации о возвращаемых значениях.

Eclipse: Juno Release 1

Java: 1.6

Реализация jsr305: com.google.findbugs.jsr305 2.0.1

  • 0
    Это Java 7 или Java 8 (есть изменения в способе, которым Eclipse обрабатывает их для Java 8)?
  • 0
    Все, что вы можете сделать, это использовать метод getSomeObj и проверить нулевое значение.
Показать ещё 3 комментария
Теги:

2 ответа

2

На самом деле @thr0wable дал хороший ответ.

Компилятор Eclipse не может гарантировать, что someEntity.getSomeObj() не будет возвращать значение null после someEntity.hasNewSomeObj(), поскольку несколько потоков могут в любое время получить доступ и изменить someEntity.

По той же причине следующий код также приведет к ошибке времени компиляции по уважительной причине:

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

Единственный способ гарантировать, что объект фактически не равен нулю, заключается в следующем:

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

ОБНОВИТЬ

С Java 8 вы должны рассмотреть возможность использования опции "Дополнительно", которая обеспечивает именно те функции, которые вам нужны:

static class SomeEntity {
    private Optional<Object> someObj;

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

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

Тогда ваш примерный код можно было бы упростить, используя выражение лямбда:

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

Я не уверен, если проверки времени компиляции уже реализованы в последней сборке JDT Java 8, но как только она будет выпущена, я думаю, что вы должны обязательно получать предупреждения/ошибки времени компиляции, если вы попытаетесь получить доступ к Optional объекту по Optional#get() без предварительной проверки Optional#isPresent().

1

В

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

Вызов someEntity.getSomeObj() может по-прежнему возвращать значение null при объявлении @Nullable, поэтому вызов getSomething() приведет к NPE.

  • 0
    Как getSomeObj () может возвращать ноль, если someEntity.hanNewSomeObj () возвращает true?
  • 3
    Я не знаю точный код, но если он выполняется многопоточным, второй поток может вызвать someEntity.setSomeObj(null) прямо между if(someEntity.hasNewSomeObj()) и someEntity.getSomeObj().getSomething() .
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню