Java "? null을 확인하는 연산자 - 뭐죠? (Ternary가 아닙니다!)
슬래시닷 스토리에서 링크된 기사를 읽다가 우연히 다음과 같은 작은 기사를 발견했다.
끝없는 포인터 테스트를 위한 단축 구문을 제공하여 늘 포인터 검사를 쉽게 하려는 최신 버전의 Java를 예로 들어 보겠습니다.으로 늘 포인터 스테이트먼트의합니다.
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#에는 유사한 연산자("--")가 있습니다.교환원) 하지만 현재 사용하고 있는 언어의 문서를 받고 싶습니다.아니면 처음 보는 3진 연산자를 사용한 것일 수도 있습니다.
감사합니다!
편집: 기사 링크:http://infoworld.com/d/developer-world/12-programming-mistakes-avoid-292
원래 아이디어는 그루비에서 나온다.Project Coin: https://wiki.openjdk.java.net/display/Coin/2009+Proposals+TOC (Elvis 및 기타 Null-Safe Operators)의 일부로 Java 7용으로 제안되었지만 아직 받아들여지지 않았습니다.
오퍼레이터 는 련련엘엘음음음음음는는는는는는는는는는는는는는는는는는는 the the the the the the the the the the the the the the the the를 만들자고 제안되었다.x ?: y
입니다.x != null ? x : y
x자리의
이 구문은 Java에는 존재하지 않으며, 제가 아는 바로는 다음 버전에 포함될 예정도 없습니다.
try-catch의 Java 8의 try-catch를 도 )NullPointerException
스타일로 를 ".
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>"
)을 사용합니다.null
을 「」orElse
.
Java 7에서 제안도 있었지만 거절당했습니다.
http://tech.puredanger.com/java7/ #syslog
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 이 반환됩니다.
참조: https://blogs.oracle.com/darcy/project-coin:-the-final-five-or-so (특히 "Elvis 및 기타 null safe 연산자")
그 결과 이 기능은 Java 7에서 고려되었지만 포함되지 않았습니다.
그루비의 안전 기준 해제 작업자예요순수 자바에서는 사용할 수 없기 때문에(슬프게도) 게시글은 단순히 잘못된 것이다(Groovy가 "Java의 최신 버전"이라고 주장하는 경우에는 약간 오해의 소지가 있다).
Java 8 lambda에서는 이를 거의 예쁘게 해결할 수 있는 util 메서드를 정의할 수 있습니다.
이는 H-MANs 솔루션의 변형이지만 여러 인수를 사용하여 오버로드된 메서드를 사용하여 여러 단계를 처리하는 대신NullPointerException
.
이 솔루션이 멋지다고 생각되더라도 Helder Pereira의 seconds one을 선호합니다.그것은 활용 방법이 필요 없기 때문입니다.
void example() {
Entry entry = new Entry();
// This is the same as H-MANs solution
Person person = getNullsafe(entry, e -> e.getPerson());
// Get object in several steps
String givenName = getNullsafe(entry, e -> e.getPerson(), p -> p.getName(), n -> n.getGivenName());
// Call void methods
doNullsafe(entry, e -> e.getPerson(), p -> p.getName(), n -> n.nameIt());
}
/** Return result of call to f1 with o1 if it is non-null, otherwise return null. */
public static <R, T1> R getNullsafe(T1 o1, Function<T1, R> f1) {
if (o1 != null) return f1.apply(o1);
return null;
}
public static <R, T0, T1> R getNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, R> f2) {
return getNullsafe(getNullsafe(o0, f1), f2);
}
public static <R, T0, T1, T2> R getNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, T2> f2, Function<T2, R> f3) {
return getNullsafe(getNullsafe(o0, f1, f2), f3);
}
/** Call consumer f1 with o1 if it is non-null, otherwise do nothing. */
public static <T1> void doNullsafe(T1 o1, Consumer<T1> f1) {
if (o1 != null) f1.accept(o1);
}
public static <T0, T1> void doNullsafe(T0 o0, Function<T0, T1> f1, Consumer<T1> f2) {
doNullsafe(getNullsafe(o0, f1), f2);
}
public static <T0, T1, T2> void doNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, T2> f2, Consumer<T2> f3) {
doNullsafe(getNullsafe(o0, f1, f2), f3);
}
class Entry {
Person getPerson() { return null; }
}
class Person {
Name getName() { return null; }
}
class Name {
void nameIt() {}
String getGivenName() { return null; }
}
언급된 많은 답변이 자바 언어에는 이 기능이 없습니다.
이 컴파일러 플러그인은 몇 가지 시나리오에서 사용할 수 있지만 제한은 거의 없습니다.
이 예에서는, 다음과 같이 기술할 수 있습니다.
public String getFirstName(Person person) {
@NullSafe
String retVal = person.getName().getGivenName();
return retVal;
}
PS: 플러그인 작성자
이게 잘 될지는 모르겠지만, 예를 들어 개인 참조가 null일 경우 런타임에 의해 대체되는 것은 무엇입니까?새로운 사람?이 경우 사용자가 예상하는 기본 초기화가 필요합니다.null 참조 예외는 피할 수 있지만 이러한 유형의 설정을 계획하지 않으면 여전히 예측할 수 없는 동작이 발생할 수 있습니다.
C#의 ? 연산자는 "coalesce" 연산자로 가장 적합할 수 있습니다.여러 식을 체인할 수 있으며 null이 아닌 첫 번째 식을 반환합니다.유감스럽게도 자바에는 없습니다.체인의 멤버가 null일 경우 ternary 연산자를 사용하여 null 체크를 수행하고 식 전체의 대안을 평가하는 것이 최선이라고 생각합니다.
return person == null ? ""
: person.getName() == null ? ""
: person.getName().getGivenName();
트라이캐치를 사용할 수도 있습니다.
try
{
return person.getName().getGivenName();
}
catch(NullReferenceException)
{
return "";
}
Java 8에서는 null-safe 호출이 실행되었습니다.
public void someMethod() {
String userName = nullIfAbsent(new Order(), t -> t.getAccount().getUser()
.getName());
}
static <T, R> R nullIfAbsent(T t, Function<T, R> funct) {
try {
return funct.apply(t);
} catch (NullPointerException e) {
return null;
}
}
오래된 Java 버전을 대체할 다른 버전을 찾는 사람이 있다면 제가 쓴 것을 사용해 보십시오.
/**
* Strong typed Lambda to return NULL or DEFAULT VALUES instead of runtime errors.
* if you override the defaultValue method, if the execution result was null it will be used in place
*
*
* Sample:
*
* It won't throw a NullPointerException but null.
* <pre>
* {@code
* new RuntimeExceptionHandlerLambda<String> () {
* @Override
* public String evaluate() {
* String x = null;
* return x.trim();
* }
* }.get();
* }
* <pre>
*
*
* @author Robson_Farias
*
*/
public abstract class RuntimeExceptionHandlerLambda<T> {
private T result;
private RuntimeException exception;
public abstract T evaluate();
public RuntimeException getException() {
return exception;
}
public boolean hasException() {
return exception != null;
}
public T defaultValue() {
return result;
}
public T get() {
try {
result = evaluate();
} catch (RuntimeException runtimeException) {
exception = runtimeException;
}
return result == null ? defaultValue() : result;
}
}
입력한 코드를 테스트하면 구문 오류가 발생합니다.따라서 Java에서는 지원되지 않습니다.Groovy는 이를 지원하며 Java 7용으로 제안되었지만 포함되지 않았습니다.
단, Java 8에서 제공되는 옵션을 사용할 수 있습니다.이것은, 같은 라인에서 무언가를 달성하는 데 도움이 될 가능성이 있습니다.https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
Android는 설치된 OS가 >= 24가 아니면 Lambda Functions를 지원하지 않으므로 Reflection을 사용해야 합니다.
// Example using doIt function with sample classes
public void Test() {
testEntry(new Entry(null));
testEntry(new Entry(new Person(new Name("Bob"))));
}
static void testEntry(Entry entry) {
doIt(doIt(doIt(entry, "getPerson"), "getName"), "getName");
}
// Helper to safely execute function
public static <T,R> R doIt(T obj, String methodName) {
try {
if (obj != null)
return (R)obj.getClass().getDeclaredMethod(methodName).invoke(obj);
} catch (Exception ignore) {
}
return null;
}
// Sample test classes
static class Entry {
Person person;
Entry(Person person) { this.person = person; }
Person getPerson() { return person; }
}
static class Person {
Name name;
Person(Name name) { this.name = name; }
Name getName() { return name; }
}
static class Name {
String name;
Name(String name) { this.name = name; }
String getName() {
System.out.print(" Name:" + name + " ");
return name;
}
}
}
퍼포먼스상의 문제가 아닌 경우는, 다음과 같이 기입할 수 있습니다.
public String getFirstName(Person person) {
try {
return person.getName().getGivenName();
} catch (NullPointerException ignored) {
return null;
}
}
언급URL : https://stackoverflow.com/questions/4390141/java-operator-for-checking-null-what-is-it-not-ternary
'source' 카테고리의 다른 글
Mac OS에서 MySQL의 innodb_buffer_pool_size 값을 변경하려면 어떻게 해야 합니까? (0) | 2022.09.08 |
---|---|
가능한 모든 패키지를 업데이트하시겠습니까? (0) | 2022.09.08 |
jQuery에서 div를 "fadeOut" 및 "삭제"하는 방법은 무엇입니까? (0) | 2022.09.08 |
서버에서 보낸 이벤트 및 php - 서버에서 이벤트를 트리거하는 항목은 무엇입니까? (0) | 2022.09.08 |
CSV 파일을 MySQL 테이블로 Import하는 방법 (0) | 2022.09.08 |