Как исправить проблему Findbugs Нулевое значение гарантированно будет разыменовано NP_GUARANTEED_DEREF

Привет, у меня есть код, о котором сообщает Findbugs как о проблеме NP_GUARANTEED_DEREF. Теперь, глядя на мой код, я не совсем понимаю, что с ним не так, может ли кто-нибудь подсказать, в чем проблема.

public void test() {
  String var = "";
  int index = 2;
  if (index == -1) {
    var = String.class.getName();
    if (var.length() == 0) {
      var = null;
    }
  } else {
    var = Integer.class.getName();
    if (var.length() == 0) {
      var = null;
    }
  }
  if (var == null) {// FINBUGS reports on this line NP_GUARANTEED_DEREF
    /*
     * There is a statement or branch that if executed guarantees that a value
     * is null at this point, and that value that is guaranteed to be
     * dereferenced (except on forward paths involving runtime exceptions).
     */
    throw new NullPointerException("NULL");
  }
}

Теперь, углубившись в ошибку в Findbugs, он выделяет два назначения var = null; как причину ошибки, но я не совсем понимаю, почему. Это не похоже на то, что я на самом деле что-то делаю с объектом var, я просто делаю проверку Null. Пример взят из реального производственного кода, но лишен всего, что не требовалось для воспроизведения ошибки. Что мне интересно, ложное срабатывание это или нет. И если нет, то что было бы подходящим решением.

Вот ссылка на подробную информацию об ошибке Findbugs: http://findbugs.sourceforge.net/bugDescriptions.html#NP_GUARANTEED_DEREF

[ОБНОВЛЕНИЕ] После получения некоторых отзывов по этой проблеме я зарегистрировал это как ложное срабатывание в системе отслеживания ошибок Findbugs на Sourceforge, ссылка https://sourceforge.net/tracker/?func=detail&aid=3277814&group_id=96405&atid=614693

Разговор о проблеме продолжится там.


person AGrunewald    schedule 16.03.2011    source источник
comment
У вас случайно не было var.equals(null) раньше? Вы уверены, что повторно запустили Findbugs для этого файла (что я обычно делаю, так это называю чистые маркеры ошибок).   -  person Grzegorz Oledzki    schedule 17.03.2011
comment
Да, я уверен, что я перезапустил Findbugs, и нет, это никогда не было var.equals(null), если бы это было так, это было бы легко понять. Как сказал jzd, это не выглядит неправильно. Если я получу дополнительное подтверждение того, что это не выглядит неправильно, я, вероятно, опубликую сообщение об ошибке (ложное срабатывание) с помощью Findbugs.   -  person AGrunewald    schedule 17.03.2011
comment
Понимаю. Я могу подтвердить такое же поведение FB на своем компьютере. Выглядит действительно странно. Что забавно, если бы вы заменили throw new NullPointerException на throw new RuntimeException, маркер ошибки исчез бы.   -  person Grzegorz Oledzki    schedule 17.03.2011
comment
Теперь, кажется, я понимаю, что они имели в виду. Формулировка сообщения не точна, но они предостерегают вас от NPE. Я предполагаю, что они считают явное использование NPE плохой практикой.   -  person Grzegorz Oledzki    schedule 17.03.2011
comment
ha интересная находка Grzegorz, я могу подтвердить вашу находку. Так что проблема здесь именно в NPE. Спасибо. Если вы поместите это в реальный ответ, я могу пометить его как ответ, который я искал.   -  person AGrunewald    schedule 17.03.2011
comment
@AGrunewald - скопировал мои комментарии в ответ   -  person Grzegorz Oledzki    schedule 17.03.2011


Ответы (4)


Понимаю. Я могу подтвердить такое же поведение FB на своем компьютере. Выглядит действительно странно. Что забавно, если бы вы заменили throw new NullPointerException на throw new RuntimeException, маркер ошибки исчез бы.

Теперь, кажется, я понимаю, что они имели в виду. Формулировка сообщения не точна, но они предостерегают вас от NPE. Я предполагаю, что они считают явное использование NPE плохой практикой.

person Grzegorz Oledzki    schedule 17.03.2011

Это ошибка в FindBugs, опубликуйте эту проблему на их странице отслеживания проблем. findbugs.sf.net

person MeBigFatGuy    schedule 19.03.2011
comment
спасибо, да, это действительно ошибка, список рассылки дал тот же ответ. Я зарегистрирую это как ошибку и соответствующим образом обновлю свой вопрос. - person AGrunewald; 22.03.2011

Хорошо, FindBugs ищет оператор или ветвь, которая гарантированно приведет к исключению нулевого указателя. Первоначально мы искали только разыменования нулевых значений. Позже мы расширили анализ для лечения

if (x == null) throw new NullPointerException()

то же самое, что и явное разыменование x. В первую очередь это было сделано для облегчения межпроцедурного анализа, чтобы методы, имеющие явные проверки значений null для своих параметров, обрабатывались так же, как методы, которые разыменовывают свои параметры без явных проверок значений null, и сообщали об ошибках, когда для таких параметров передаются значения null.

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

Я не совсем уверен, какова цель приведенного выше кода. В тех точках, где вы присваиваете значение null переменной var, вы создаете ситуацию, которая приведет к явному генерированию исключения нулевого указателя ниже. Это действительно то поведение, которое вы хотите?

person Bill    schedule 13.04.2011
comment
Обсуждение продолжается в системе отслеживания ошибок SourceForge. - person AGrunewald; 14.04.2011

При более внимательном рассмотрении определения сообщения об ошибке здесь говорится:

Существует оператор или ветвь, выполнение которых гарантирует, что значение равно null в этой точке, и это значение гарантированно будет разыменовано (за исключением прямых путей, связанных с исключениями времени выполнения).

Что заставляет меня думать, что это либо просто сообщает вам, что var будет нулевым, либо что-то на самом деле заставляет findbugs думать, что var упоминается внутри оператора if.

Код, который вы разместили, выглядит нормально, я бы дважды проверил, что var не доступен в истинном коде.

Единственное, что я мог бы изменить, это написать сравнение в обратном порядке:

if (null == var)

Таким образом, очевидно, что если вы пропустите один из =/

person jzd    schedule 16.03.2011
comment
Спасибо за ответ, jzd, хотя я согласен с вами по поводу замены сравнения, к сожалению, это не меняет того, что сообщает Findbugs. - person AGrunewald; 16.03.2011
comment
@Agrune, я посмотрел определение, и теперь я чувствую себя лучше в своем ответе. Я обновил его, чтобы включить определение. - person jzd; 16.03.2011