I가 갖는 클래스가 hasField
기능하는 필드가 존재하지 널 및 여부 검사 getField
기능이 복귀 필드의 값 (또는 널 (null)이 아닌 경우, 본).
내가 전화를 내 코드에서 getField
바로 확인 후 hasField
, 나는 getField가 null을 반환하지 않을 것을 알고 있지만, IDE 검사 ( 일정한 조건 및 예외 ) 알고하지 않습니다. 나는 방법의 무리 얻을 method name
을 생성 할 수NullPointerException
나는이 경고 멀리 갈 수 있도록 깨끗한 방법을 찾기 위해 노력하고있어.
해결 방법
여기에 내가 할 수있는 몇 가지 해결 방법이있다 그러나 나는이 해키를 모두 찾을 수 :
- 서라운드
getField
와 함께Objects.requireNotnull
, 코드가없는 조합 없을 것이다. 이 코드가 약간 덜 읽을 수 같은 것을하고 싶지 않은 것이다. - 나는이 안전 알고 억제 경고. 다시 이것이 우리의 코드에서 장소의 무리에 무슨 일이 일어날으로 바람직하지.
- 경고를 무시합니다. 경고 섹션이 너무 시끄러운 것해서이 경우 우리는 합법적 인 경고를 놓칠 수 있습니다.
이상적인 솔루션
어떻게 든하면되는 방식으로 경고를 설정할 수있을 것 hasField
사실, 다음 getField
null이 아닌를 반환합니다? 나는 들여다 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를 말할 수있을 싶어.
공개 나는이 서브 시스템에 대한 책임을하게 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); }
}