Java null 확인 .equals () 대신 == 사용


125

Java에서는 null 검사를 할 때 .equals () 대신 ==을 사용해야한다고 들었습니다. 그 이유는 무엇입니까?


12
가장 쉬운 방법은 null 검사를 시도 equals()하고 보는 것입니다. 시도하면 즉시 분명해질 것입니다
Goran Jovic

그건 그렇고, 키워드 "java null check"(따옴표 제외)를 사용한 Google 검색 은 여기에 대한 답변과 동일한 정보를 가진 이 스레드를 가장 많이 조회 한 사람 중 하나로 저를주었습니다 .
Mitch Schwartz

답변:


179

완전히 다른 두 가지입니다. ==변수에 포함 된 개체 참조 (있는 경우)를 비교합니다. 평등이 의미하는 바에 대한 계약에 따라 .equals()두 개체가 동일한 지 확인합니다 . 계약에 따라 두 개의 서로 다른 개체 인스턴스가 "동일"할 수 있습니다. 그리고 equals메서드 이기 때문에 null참조에서 호출하려고 하면 NullPointerException.

예를 들면 :

class Foo {
    private int data;

    Foo(int d) {
        this.data = d;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null || other.getClass() != this.getClass()) {
           return false;
        }
        return ((Foo)other).data == this.data;
    }

    /* In a real class, you'd override `hashCode` here as well */
}

Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances

System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition

Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it

System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything

System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null

무슨 뜻 public int data입니까?
Jé Queue

@Xepoch : 아니요, 일반적으로 퍼블릭 필드를 생성하지 않습니다 (이 예에서는 어느 쪽이든 상관이 없지만). 왜?
TJ Crowder

@TJ Crowder "그들은 완전히 다른 두 가지입니다 .."일반적으로 그렇습니다. 그러나 내 이해가 정확하다면 둘 다의 기본 구현은 동일합니다. 소스 코드를 보면 .equals ()는 기본적으로 == 검사를 수행합니다. hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/…
Ayush

1
@Ayush- Object네, 그게 기본값입니다 . 하지만 많은 수의 JDK 클래스에 의해 재정의됩니다. 그러나 요점은 구현에 관한 것이 아니라 의미에 관한 것입니다. (참고 : JDK7은 매우 구식입니다.)
TJ Crowder

맞아요, 그게 말이 되네요, 그냥 명확히하고 싶었어요.
Ayush

38

당신이 호출 할 경우 .equals()null당신은 얻을 것이다NullPointerException

따라서 항상 적용되는 메서드를 호출하기 전에 nullity를 확인하는 것이 좋습니다.

if(str!=null && str.equals("hi")){
 //str contains hi
}  

참조


34
귀하의 예는 일반적으로 if ("hi".equals(str)).
ColinD

3
@ user368186 : 요점은 equals 메서드에 null 검사가 포함되어 있는지 여부가 아닙니다. 개체 참조가 null이면 equals 메서드를 입력하지 않고도 호출 someObject.equals(null)이 a NullPointerException를 발생시킵니다.
Dave Costa

2
여기 시연 동의 @ColinD
Jigar 조시에게

2
항상 null을 피하는 것이 좋습니다. 따라서 null 검사가 전혀 필요하지 않습니다.).
fwielstra 2010

2
당신은 항상 사용할 수 있습니다 Objects.equals(a, b)그것은 NullPointerException이 인상되지 않습니다,하지만 여전히 "A"와 "B"의 "동일"방법에 따라 달라집니다
도미니크 밍크

29

허용 된 답변 ( https://stackoverflow.com/a/4501084/6276704 ) 외에 :

Java 1.7 이후로 null 일 수있는 두 개체를 비교하려면 다음 함수를 권장합니다.

Objects.equals(onePossibleNull, twoPossibleNull)

java.util.Objects

이 클래스는 개체에서 작동하기위한 정적 유틸리티 메서드로 구성됩니다. 이러한 유틸리티에는 개체의 해시 코드를 계산하고, 개체에 대한 문자열을 반환하고, 두 개체를 비교하기위한 null-safe 또는 null 허용 메서드가 포함됩니다.

이후 : 1.7


2
다른 사람들에게 더 잘 보이게 만들기 위해 (chin90의 답변 또는 JavaDoc 참조 ) : Objects.equals(null, null)반환됩니다 true-명심하십시오.
토마스

20

Java 0 또는 null은 객체가 아닌 단순 유형입니다.

equals () 메소드는 단순 유형에 대해 빌드되지 않습니다. 단순 유형은 ==와 일치 할 수 있습니다.


4
명백한 "NullPointerException이 반환됩니다"herp derp 대답과는 반대로 가장 유용한 실제 대답에 대해 찬성 투표를합니다.
volk

4
foo.equals(null)

foo가 null이면 어떻게 되나요?

NullPointerException이 발생합니다.


3

Object 변수가 null이면 equals () 메서드를 호출 할 수 없으므로 null 객체 참조 검사가 적절합니다.


2

null 개체 참조에 대해 equals를 호출하면 null 포인터 예외가 발생합니다.


2

소스 에 따르면 기본 메소드 구현에 무엇을 사용해야하는지 중요하지 않습니다.

public boolean equals(Object object) {
    return this == object;
}

그러나 equals커스텀 클래스에서는 확신 할 수 없습니다 .


그것은 중요합니다. 왜냐하면 (또는 재정의 된 메서드가 말도 안되는 경우에는 다른 것을 equals반환 false하거나 유발할 수 있기 때문 입니다). NullPointerExceptionequals

2

=> .equals 메서드를 사용하면

if(obj.equals(null))  

// Which mean null.equals(null) when obj will be null.

obj가 null이되면 Null Point Exception이 발생합니다.

그래서 우리는 ==를 사용해야합니다

if(obj == null)

참조를 비교할 것입니다.


2

Object.equals는 null 안전하지만 두 개체가 null이면 object.equals는 true를 반환하므로 object.equals를 사용하기 전에 비교하는 개체가 null이 아닌지 (또는 null 값을 보유) 확인해야합니다. 비교.

String firstname = null;
String lastname = null;

if(Objects.equals(firstname, lastname)){
    System.out.println("equal!");
} else {
    System.out.println("not equal!");
}

위의 예제 스 니펫은 equal을 반환합니다!


JavaDoc에 명시된대로 (항상 읽는 것이 현명합니다) Consequently, if both arguments are null, true is returned. ...:)
Thomas

1

equal은 Object 클래스에서 파생 된 함수이므로이 함수는 클래스의 항목을 비교합니다. null과 함께 사용하면 클래스 내용이 null이 아니기 때문에 false를 반환합니다. 또한 ==는 객체에 대한 참조를 비교합니다.


글쎄, 결과는 false또는 NullPointerException( equals나쁜 것으로 대체되지 않은 경우 ) 일 수 있습니다.

1

여기서 예는 어디 str != null하지만 str.equals(null)사용시org.json

 JSONObject jsonObj = new JSONObject("{field :null}");
 Object field = jsonObj.get("field");
 System.out.println(field != null);        // => true
 System.out.println( field.equals(null)); //=> true
 System.out.println( field.getClass());  // => org.json.JSONObject$Null




편집 : 여기에 org.json.JSONObject $ Null 클래스가 있습니다.

/**
 * JSONObject.NULL is equivalent to the value that JavaScript calls null,
 * whilst Java's null is equivalent to the value that JavaScript calls
 * undefined.
 */
private static final class Null {

    /**
     * A Null object is equal to the null value and to itself.
     *
     * @param object
     *            An object to test for nullness.
     * @return true if the object parameter is the JSONObject.NULL object or
     *         null.
     */
    @Override
    public boolean equals(Object object) {
        return object == null || object == this;
    }  
}

여기서 문제 field.equals(null)는 사실 을 반환 한다는 것입니다. 이것은 일반적인 Java 동작을 깨뜨려 혼란 스럽습니다. field.equals("null")적어도 내 관점에서는 에서만 작동합니다 . 도서관 개발자들이 이것이 지원하기에 좋을 것이라고 생각한 이유를 모르겠습니다.
Tom

Btw, 첫 번째 문장에 문법 문제가 있으며 의미가 명확하지 않습니다. "여기에 예가 있습니다.str != nullstr.equals(null)반환 true사용하는 경우 org.json을 ."?
Tom

jsonObject그 이유 field는 null이 아닌 "필드"키가 포함되어 있기 때문이라고 생각합니다 . json.org.JSONObject$Null 개체 를 포함하는 참조가 있습니다.
dina

예, 그러나 나는 대신 사용하고 Null싶습니다 . 그러나 나는 그들이 Strings를 요구하지 않기 위해 그렇게했다고 생각합니다. 그러나 그 lib를 사용하더라도 여전히 거의 항상 문제입니다. null"null"field.equals(null)
Tom

0

그래서 나는 결코 혼란스럽지 않고이 솔루션의 문제를 피합니다.

if(str.trim().length() <=0 ) {
   // is null !
}

5
STR가 null 인 경우 이것은 NPE 될 것입니다
typoerrpr

추가로 문자열 ( ""길이 0)은 null참조와 완전히 다른 것입니다 (즉 , 문자열 없음 ).
토마스

0

어제 밤에이 사건을 만났습니다.
나는 단순히 다음과 같이 결정합니다.

null에 대해 equals () 메소드 가 존재하지 않습니다. 따라서 존재하지 않는 메소드 가 없으면 호출 할 수 없습니다 .->>> 이것이 확인을 위해 == 를 사용하는 이유입니다.

null


0

당신은 데메테르의 법칙을 위반합니다. 그렇기 때문에 디자인 자체를 리팩토링하는 것이 좋습니다. 해결 방법으로 선택 사항을 사용할 수 있습니다.

   obj = Optional.ofNullable(object1)
    .map(o -> o.getIdObject11())
    .map(o -> o.getIdObject111())
    .map(o -> o.getDescription())
    .orElse("")

위는 객체의 계층 구조를 확인하는 것이므로 간단히 사용하십시오.

Optional.ofNullable(object1) 

확인할 개체가 하나만있는 경우

도움이 되었기를 바랍니다 !!!!


-3

당신은 항상 할 수 있습니다

if (str == null || str.equals(null))

이것은 먼저 개체 참조를 확인한 다음 참조가 null이 아닌 경우 개체 자체를 확인합니다.


(캐릭터 == null의 || str.equals (NULL) || str.equals ( ""))의 경우
루 Morda

나는 당신의 대답을 사용하고 빈 문자열에 대한 수표를 추가했습니다! 실수하지 않았다면 null과 ""는 같은 것이 아닙니다.
Lou Morda

4
null에 대한 두 번째 검사를 추가하는 것이 완전히 중복되지 않습니까?
Justin Rowe

2
@JustinRowe 중복 일뿐만 아니라 매우 잘못되었습니다. 제발, 절대로 x.equals(null).

@Tom, JustinRowe 왜 이것이 중복되거나 완전 쓰레기가 아닌지 위의 내 대답을 참조하십시오. stackoverflow.com/questions/4501061/…
dina
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.