Как исправить проблему в FindBugs "нулевое значение гарантированно будет разыменован" НП гарантировано оператор deref


Привет, у меня есть некоторый код, который сообщается как имеющий проблему 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, я просто делаю нулевую проверку. Пример взят из реального производственный код, но лишенный всего, что не было необходимо для воспроизведения ошибки. То, что я задаюсь вопросом, является ли это ложным положительным или нет. А если нет, то каково было бы соответствующее исправление.

Вот ссылка на деталь ошибки Findbugs: http://findbugs.sourceforge.net/bugDescriptions.html#NP_GUARANTEED_DEREF

[UPDATE] после получения некоторых отзывов по этому вопросу я теперь зарегистрировал это как ложное срабатывание в FindBugs Bugtracker на Sourceforge ссылка https://sourceforge.net/tracker/?func=detail&aid=3277814&group_id=96405&atid=614693

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

4 5

4 ответа:

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

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

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

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

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

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

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

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

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

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

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

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

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

if (null == var)

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