[java] 자바 “?” null 검사 연산자-무엇입니까? (삼항이 아닙니다!)

나는 slashdot 이야기에서 링크 된 기사를 읽고 있었고,이 작은 정보를 발견했습니다.

끝없는 포인터 테스트를위한 속기 구문을 제공하여 널 포인터 검사를 더 쉽게 만드는 최신 버전의 Java를 사용하십시오. 각 메서드 호출에 물음표를 추가하기 만하면 null 포인터에 대한 테스트가 자동으로 포함되어 다음과 같이 쥐의 if-then 문을 대체합니다.

    public String getPostcode(Person person) {
      String ans= null;
      if (person != null) {
        Name nm= person.getName();
        if (nm!= null) {
          ans= nm.getPostcode();
        }
      }
      return ans
    } 

이것으로 :

public String getFirstName(Person person) {
      return person?.getName()?.getGivenName();
    } 

나는 인터넷을 샅샅이 뒤졌지만 (좋아, “자바 물음표”에 대한 인터넷 검색에 적어도 15 분을 보냈다) 아무것도 얻지 못했다. 그래서, 내 질문 : 이것에 대한 공식 문서가 있습니까? C #에 유사한 연산자 ( “??”연산자)가 있지만 작업중인 언어에 대한 문서를 얻고 싶습니다. 전에 본적이 없다.

감사!

편집 : 기사 링크 : http://infoworld.com/d/developer-world/12-programming-mistakes-avoid-292



답변

원래 아이디어는 그루비에서 나왔습니다. 프로젝트 코인 : https://wiki.openjdk.java.net/display/Coin/2009+Proposals+TOC(Elvis 및 기타 Null-Safe 연산자)의 일부로 Java 7 용으로 제안 되었지만 아직 승인되지 않았습니다. .

관련 엘비스 연산자는? 만들기 위해 제안되었다 x ?: y위한 속기 x != null ? x : yx는 복잡한 표현 인 경우 특히 유용합니다.


답변

이 구문은 Java에 존재하지 않으며 내가 아는 향후 버전에 포함될 예정이 아닙니다.


답변

Java 7에 제안이 있었지만 거부되었습니다.

http://tech.puredanger.com/java7/#null


답변

“?”부족을 해결하는 한 가지 방법 try-catch의 오버 헤드없이 Java 8을 사용하는 연산자 ( NullPointerException언급 한대로 다른 곳에서 시작된 것을 숨길 수도 있음 )는 Java-8-Stream 스타일의 “파이프”메서드에 대한 클래스를 만드는 것입니다.

public class Pipe<T> {
    private T object;

    private Pipe(T t) {
        object = t;
    }

    public static<T> Pipe<T> of(T t) {
        return new Pipe<>(t);
    }

    public <S> Pipe<S> after(Function<? super T, ? extends S> plumber) {
        return new Pipe<>(object == null ? null : plumber.apply(object));
    }

    public T get() {
        return object;
    }

    public T orElse(T other) {
        return object == null ? other : object;
    }
}

그러면 주어진 예는 다음과 같습니다.

public String getFirstName(Person person) {
    return Pipe.of(person).after(Person::getName).after(Name::getGivenName).get();
}

[편집하다]

더 깊이 생각해 보면 표준 Java 8 클래스를 사용해야 만 실제로 동일한 결과를 얻을 수 있다는 것을 알았습니다.

public String getFirstName(Person person) {
    return Optional.ofNullable(person).map(Person::getName).map(Name::getGivenName).orElse(null);
}

이 경우 매개 변수로 전달하는 "<no first name>"대신 기본값 (예 :)을 선택할 수도 있습니다 .nullorElse


답변

참조 : https://blogs.oracle.com/darcy/project-coin:-the-final-five-or-so (특히 “Elvis 및 기타 널 안전 연산자”).

그 결과이 기능은 Java 7 용으로 고려되었지만 포함되지 않았습니다.


답변

그것은 실제로 Groovy의 안전 역 참조 연산자 입니다. 순수한 Java에서는 사용할 수 없으므로 (슬프게도) 게시물이 잘못되었습니다 (또는 Groovy가 “Java의 최신 버전”이라고 주장하는 경우 약간 오해의 소지가 있음).


답변

Java에는 정확한 구문이 없지만 JDK-8부터는 다양한 메소드를 사용할 수있는 Optional API 가 있습니다. 따라서 null 조건부 연산자를 사용하는 C # 버전 :

return person?.getName()?.getGivenName();

선택적 API를 사용하여 Java에서 다음과 같이 작성할 수 있습니다 .

 return Optional.ofNullable(person)
                .map(e -> e.getName())
                .map(e -> e.getGivenName())
                .orElse(null);

person, getName또는 중 하나 getGivenName가 null이면 null이 반환됩니다.