NullPointerException이 경고를 생성 할 수 있습니다에 대한 인 IntelliJ 코드 검사 개선

리시 두아 :

I가 갖는 클래스가 hasField기능하는 필드가 존재하지 널 및 여부 검사 getField기능이 복귀 필드의 값 (또는 널 (null)이 아닌 경우, 본).

내가 전화를 내 코드에서 getField바로 확인 후 hasField, 나는 getField가 null을 반환하지 않을 것을 알고 있지만, IDE 검사 ( 일정한 조건 및 예외 ) 알고하지 않습니다. 나는 방법의 무리 얻을 method name을 생성 할 수NullPointerException

나는이 경고 멀리 갈 수 있도록 깨끗한 ​​방법을 찾기 위해 노력하고있어.

해결 방법

여기에 내가 할 수있는 몇 가지 해결 방법이있다 그러나 나는이 해키를 모두 찾을 수 :

  1. 서라운드 getField와 함께 Objects.requireNotnull, 코드가없는 조합 없을 것이다. 이 코드가 약간 덜 읽을 수 같은 것을하고 싶지 않은 것이다.
  2. 나는이 안전 알고 억제 경고. 다시 이것이 우리의 코드에서 장소의 무리에 무슨 일이 일어날으로 바람직하지.
  3. 경고를 무시합니다. 경고 섹션이 너무 시끄러운 것해서이 경우 우리는 합법적 인 경고를 놓칠 수 있습니다.

이상적인 솔루션

어떻게 든하면되는 방식으로 경고를 설정할 수있을 것 hasField사실, 다음 getFieldnull이 아닌를 반환합니다? 나는 들여다 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

내가 이상적으로 hasSample에 해당하는 경우 경우 getSample가 null가 아닌 것을 IDE를 말할 수있을 싶어.

Tagir Valeev 보낸 사람 :

공개 나는이 서브 시스템에 대한 책임을하게 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를 리팩토링 제안 할 수 있습니다 :

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=478657&siteId=1