자바 : 객체가 null인지 확인하는 방법?


87

웹에서 이미지를 검색하는 응용 프로그램을 만들고 있습니다. 이미지를 검색 할 수없는 경우 다른 로컬 이미지를 사용해야합니다.

다음 줄을 실행하는 동안 :

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable.equals(null)) {
  drawable = getRandomDrawable();
}

drawable이 null 인 경우 if (drawable.equals (null)) 줄에서 예외가 발생합니다.

null 인 경우 예외를 throw하지 않고 로컬 이미지를 검색하기 위해 drawable의 값을 어떻게 확인해야하는지 아는 사람이 있습니까 (execute drawable = getRandomDrawable ())?


23
if (drawable == null) 사용 NULL 개체에 대한 모든 메서드 호출은 NullPointerException입니다.
diciu

3
댓글 대신 평범한 답을 써보는 건 어때?
deamon

@JaredBurrows 질문의 목적에 위배되는 방식으로 질문의 코드를 편집하지 마십시오!
Gilles 'SO- 그만 사악한'

@Gilles 편집 코멘트를 읽고 코드를 더 읽기 쉽게 만들었습니다.
Jared Burrows

@JaredBurrows 아니요, 편집은 "서식"변경이 아닙니다. 당신은 질문의 대상이었던 비 작동 코드를 질문에 대한 논쟁을 불러 일으키는 작동 코드로 변경했습니다.
질 'SO-정지 존재 악마'

답변:


35

편집 된 Java 8 솔루션 :

final Drawable drawable = 
    Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath()))
        .orElseGet(() -> getRandomDrawable());

drawable final이 경우 선언 할 수 있습니다 .

Chasmo가 지적했듯이 Android는 현재 Java 8을 지원하지 않습니다. 따라서이 솔루션은 다른 상황에서만 가능합니다.


7
아마도 좋은 생각은 아닐 것입니다. 조건의 양쪽이 모두 평가되는 Fortran 60으로 돌아가서 하나만 사용됩니다. 사용하지 않는 분기에 계산이있는 경우에는 좋지 않습니다. 대부분의 경우 사실이므로 일반적으로 유용한 방법이 아닙니다. 조건을 Common클래스 로 옮기고 대체 URL을 제공하고 책임을 함께 유지할 수 있습니다.
Pete Kirkham

1
이 예제는 이제 Java 8로 완전히 다시 작성되었으므로 내 솔루션은 더 이상 쓸모없는 평가로 고통받지 않습니다 (@PeteKirkham이 원래 솔루션에서 지적했듯이).
deamon

1
Android는 Java 8을 지원하지 않습니다. 최대 Java 7 (kitkat이있는 경우) 만 지원하며 invokedynamic은없고 새로운 구문 설탕 만 지원합니다. 그 외에도 Optional.of값이 null이 아니므로 orElseGet는 불필요합니다. Optional.ofNullable이 경우에 사용해야합니다 .
Martin Seeler 2014 년

179
Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable == null) {
    drawable = getRandomDrawable();
}

equals()메서드는 값이 같은지 확인 합니다. 즉, 두 개체 의 내용 을 비교 합니다. null이 객체가 아니기 때문에 객체의 내용을의 내용과 비교하려고 할 때 충돌이 발생합니다 null.

==위한 연산자를 검사 기준 은 두 개체가 실제로 있는지 보이는 것을 의미 평등 매우 동일한 개체 . 이것은 개체가 실제로 존재할 필요는 없습니다. 존재하지 않는 두 개체 ( null참조)도 동일합니다.


56
매우 귀중한 팁을 추가하고 싶습니다. 비교할 문자열이나 상수가 있다면 항상 equals 절에서 먼저 두십시오. (if ( "coyote".equals (myDogString))))이 (if (myDogString.equals ( "coyote")))보다 훨씬 낫습니다. 두 번째 경우에는 myDogString이 null 일 수 있고 첫 번째 경우에는 NPE를 던지기 때문입니다. myDogString이 null인지 여부는 중요하지 않습니다.
Thorsten S.

20
요다 조건으로 알려진 "코요테 경우, 개는 ..."
토마스

1
또한 Java 7에는 Objects.equals () 메서드가
있으므로

21

이 접근 방식을 사용합니다.

if (null == drawable) {
  //do stuff
} else {
  //other things
}

이렇게하면 줄의 가독성이 향상됩니다. 소스 파일을 빠르게 읽을 때 null 검사임을 알 수 있습니다.

다음과 .equals()같은 객체를 호출 할 수없는 이유에 관해서는 null; 가지고있는 객체 참조 (즉 'drawable') 실제로 null이면 힙의 객체를 가리 키지 않습니다. 이는 호출이 equals()성공할 수 있는 힙에 개체가 없음을 의미합니다 .

행운을 빌어 요!


4
나도 실수로 할당되지 않도록 보호하는 방법으로 if (<constant> == <variable>) 구문을 선호합니다.
Scott

8

DIY

private boolean isNull(Object obj) {
    return obj == null;
}

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (isNull(drawable)) {
    drawable = getRandomDrawable();
}

6
drawable.equals(null)

위의 줄은 드로어 블 객체에서 "equals (...)"메서드를 호출합니다.

따라서 드로어 블이 null이 아니고 실제 객체 인 경우 "equals (null)"메서드를 호출하면 "false"가 반환됩니다.

그러나 "drawable"이 null이면 null 객체에 대해 "equals (...)"메서드를 호출하는 것을 의미하고, 존재하지 않는 객체에 대해 메서드를 호출하는 것을 의미하므로 "NullPointerException"이 발생합니다.

객체가 존재하고 null이 아닌지 확인하려면 다음을 사용하십시오.

if(drawable == null) {
    ...
    ...
}

위의 조건에서 참조 변수 "drawable"이 null인지 또는 일부 값 (객체에 대한 참조)이 포함되어 있는지 확인하므로 확인시 drawable이 null 인 경우 예외가 발생하지 않습니다.

null == null

유효합니다.


5

if (yourObject instanceof yourClassName)로 평가합니다 false경우 yourObject입니다 null.


0

NullPointerException을 잡는 것이 약간 더 효율적일 것입니다. 위의 메소드는 런타임이 널 포인터를 두 번 확인 함을 의미합니다.


1
이중 체크인 if x == null솔루션 은 어디에 있습니까 ?
deamon

if 문 다음에 런타임은 개체가 사용될 때 null 포인터를 다시 확인합니다. 그래도 이것이 컴파일러에 의해 최적화되었는지 여부는 모르겠습니다.
Tom R

4
이것은 예외를 제어 흐름으로 사용하는 일반적인 통념에 위배됩니다.
James

1
예외는 전체 스택 추적을 생성해야하기 때문에 매우 비쌉니다.
deamon

0

Google Guava libs 를 사용 하여 is-null-check 처리 (데몬의 업데이트)

Drawable drawable = Optional.of(Common.getDrawableFromUrl(this, product.getMapPath())).or(getRandomDrawable());

Optional지금 Java 8을 더 잘 사용하십시오 .
deamon

-1

Oracle Java 소스 개발자에게 몇 가지 아이디어를 제공하기 위해 :-)

이 솔루션은 이미 .Net에 존재하며 더 읽기 쉽습니다!

Visual Basic .Net에서

Drawable drawable 
    = If(Common.getDrawableFromUrl(this, product.getMapPath())
        ,getRandomDrawable()
        )

C #에서

Drawable drawable 
    = Common.getDrawableFromUrl(this, product.getMapPath() 
        ?? getRandomDrawable();

이러한 솔루션은 새 연산자를 추가 할 때만 람다 식을 사용하지 않고 선택적 Java 솔루션 (원래 값이 null 인 경우에만 기본 문자열이 평가됨)으로 강력합니다.

Java 솔루션과의 차이점을 빠르게 확인하기 위해 2 개의 Java 솔루션을 추가했습니다.

Java에서 선택 사항 사용

Drawable drawable = 
    Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath()))
        .orElseGet(() -> getRandomDrawable());

자바에서 {} 사용

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable != null)
    {
    drawable = getRandomDrawable();
    }

개인적으로, VB.Net과 같은 I 그러나 내가 선호하는 ?? C#또는 if {}솔루션을 자바로 ... 그리고 당신은?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.