Как исправить проблему Findbugs «Null-значение гарантированно разыменовывается» NP_GUARANTEED_DEREF - PullRequest
5 голосов
/ 16 марта 2011

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

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

Разговор о проблеме будет продолжен там.

Ответы [ 4 ]

5 голосов
/ 17 марта 2011

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

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

3 голосов
/ 19 марта 2011

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

2 голосов
/ 13 апреля 2011

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

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

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

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

0 голосов
/ 16 марта 2011

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

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

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

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

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

if (null == var)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...