Улучшение Intellij инспекции кода для предупреждения может привести к NullPointerException

Риши Дуа:

У меня есть класс с hasFieldфункцией , которая проверяет , является ли поле присутствует и не равно нулю, и getFieldфункция , которая возвращает значение поля (или нуль , если нет).

В моем коде , когда я вызываю getFieldсразу после проверки hasField, я знаю , что ПолучитьПолеЗаголовка не собирается возвращать нуль, но IDE Inspection ( постоянные условия и исключения ) не знает , что. Я получаю кучу метод method nameможет производитьNullPointerException

Я пытаюсь найти чистый способ сделать это предупреждение уйти.

обходные

Вот некоторые обходные пути я мог бы сделать, но я нахожу все эти Hacky:

  1. Surround getFieldс Objects.requireNotnull, код не будет оп. Предпочли бы не делать это , как это делает код немного менее читабельным.
  2. Подавить предупреждения, когда я знаю, что это безопасно. Опять же не является предпочтительным, так как это будет происходить на кучу мест в коде.
  3. Игнорировать предупреждения. В этом случае мы могли бы пропустить предупреждения законных только потому, что предупреждения раздел будет слишком шумно.

Идеальное решение

Смогу ли я каким - то образом настроить предупреждения таким образом , что , если hasFieldэто правда, то getFieldвернет ненулевой? Я посмотрел в JetBrains контракта аннотаций , но делать то , что я хочу здесь , кажется, за то , что поддерживается @Contract

Пример кода

Вот минимальный рабочий образец кода, который демонстрирует проблему:

import javax.annotation.Nullable;

public class Hello {

  private Hello(){}
  public static void main(String[] args) {
    TestClass test1 = new TestClass(null);
    if (test1.hasSample()) {
      System.out.println(test1.getSample().equals("abc"));
    }
 }
}

class TestClass {
  private final String sample;

  TestClass(String field) { this.sample = field; }

  boolean hasSample() { return sample != null; }

  @Nullable public String getSample() { return sample; }
}

Я получаю следующее предупреждение

Способ вызова equalsможет привести кNullPointerException

Я бы в идеале хотели бы быть в состоянии сказать, что IDE getSample не равно нулю, когда hasSample верно.

Тагир Валеев:

Раскрытие Я IntelliJ IDEA разработчик отвечает за эту подсистему


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

  • Эти методы , как hasSample()и getSample()вызываются из того же класса
  • Вызываемые методы не могут быть переопределены (частный / статический / Окончательный / объявлен в окончательном классе)

Например, эта функция работает в следующем коде:

final class TestClass { // if final is removed, the warning will appear again
  private final String sample;

  TestClass(String field) { this.sample = field; }

  boolean hasSample() { return sample != null; }

  @Nullable
  public String getSample() { return sample; }

  @Override
  public String toString() {
    if (hasSample()) {
      return "TestClass: "+getSample().trim(); // no warning on trim() invocation here
    }
    return "TestClass";
  }
}

На данный момент, я могу только предложить рефакторинга свои API, чтобы OPTIONALS как это:

import java.util.Optional;

public class Hello {

  private Hello(){}
  public static void main(String[] args) {
    TestClass test1 = new TestClass(null);
    test1.getSample().ifPresent(s -> System.out.println(s.equals("abc")));
    // or fancier: test1.getSample().map("abc"::equals).ifPresent(System.out::println);
  }
}

final class TestClass {
  private final String sample;

  TestClass(String field) { this.sample = field; }

  public Optional<String> getSample() { return Optional.ofNullable(sample); }
}

рекомендация

отhttp://10.200.1.11:23101/article/api/json?id=478656&siteId=1