Мне очень удобно использовать @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
На самом деле @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()
.
В
if(someEntity.hasNewSomeObj()) {
someOperator.doStuff(someEntity.getSomeObj().getSomething());
}
Вызов someEntity.getSomeObj()
может по-прежнему возвращать значение null
при объявлении @Nullable
, поэтому вызов getSomething()
приведет к NPE.
someEntity.setSomeObj(null)
прямо между if(someEntity.hasNewSomeObj())
и someEntity.getSomeObj().getSomething()
.
getSomeObj
и проверить нулевое значение.