2014-07-07 5 views
3

나는 equals 메서드를 만들었습니다. 나는 두 가지 방법으로 그것을 할 수 있다고 생각하지만 자바는 동의하지 않는 것 같습니다. 제가 일하는 첫 번째 예가 여기 있습니다.|| operator

public class HelloWorld { 

    public boolean equals(Object rhs){ 
     if(this==rhs){ 
      return true; 
     }else if(rhs==null || this.getClass() != rhs.getClass()){ 
      return false; 
     }else{ 

      HelloWorld tmp =(HelloWorld)rhs; 
      return true; 
     } 
    } 

    public static void main(String[] args){ 
     HelloWorld c = new HelloWorld(); 
     System.out.println(c.equals(null)); 

    } 
} 

그리고 두 번째 예제가 작동하지 않습니다. false를 반환하는 대신 nullpointerexception을 얻습니다.

public class HelloWorld { 

    public boolean equals(Object rhs){ 
     if(this==rhs){ 
      return true; 
     }else if(this.getClass() != rhs.getClass() || rhs==null){ 
      return false; 
     }else{ 

      HelloWorld tmp =(HelloWorld)rhs; 
      return true; 
     } 
    } 

    public static void main(String[] args){ 
     HelloWorld c = new HelloWorld(); 
     System.out.println(c.equals(null)); 

    } 
} 

내 질문에 다음 ... 코드의 두 조각 사이의 유일한 차이는 첫 번째 조각 나는

rhs ==null ||... 

를 작성한 그리고 두 번째 조각이의 반대편에 있다는 것입니다 는 OR 연산자는 너무

...|| rhs==null 

이유는 첫 번째 경우는 나에게 Nullpointer하지만 않습니다 두 번째 경우를주지 못할 것이다? 왜 OR 연산자의 어느쪽에 부울 문을 쓰는 것이 중요할까요?

답변

2

|| 연산자의 오른쪽이 실행되지 JLS section 15.24 따라 좌측이 true로 평가 될 경우 : || 연산자 | 같다

조건부 OR 연산자 (§15.22.2)하지만, 그 오른쪽 피연산자가 확인 된 경우에만 값 그 왼쪽 피연산자는입니다..

그래서 첫 번째 경우, rhs == null이 true로 평가되므로 rhs.getClass()은 실행되지 않습니다 - 그렇지 않으면 NullPointerException을 던졌다.

두 번째 경우에는 무조건 rhs.getClass()을 실행하므로 예외가 발생합니다.

|| 대신 |을 사용하면 두 경우 모두 예외가 발생합니다.

6

조건부 "OR"연산자 인 ||은 결과가 이미 결정될 수 있으므로 왼쪽 표현식이 true 인 경우 올바른 표현식을 평가하지 않기 때문에 중요합니다. 이것은 "단락"동작으로 알려져 있습니다.

Section 15.24 of the JLS이 커버 :

조건부 OR 연산자 || 연산자는 같다 | (§15.22.2), 왼쪽 피연산자의 값이 false 인 경우에만 오른쪽 피연산자를 평가합니다.

오른쪽 표현식은 평가되지 않으므로 NullPointerException이 사용되지 않습니다.

(좌측이 true 경우 && 조건 "AND"연산자는 또한 "단락"는 오직 우측을 평가할 것이다.)

1

Joshua Bloch의 "Effective Java"장 3에서 equals 메소드를 올바르게 구현 한 방법을 따르는 것이 좋습니다.

equals를 구현하는 경우 hashCode도 구현해야합니다.

0

'||' 이는 단락 회로의 동작과 조건부 OR인데, 첫 번째 조건이 참이면 두 번째 조건은 평가되지 않았습니다.

예를 들어 (A || B)를 사용하는 경우 --- A가 true이면 B는 평가되지 않습니다.

그래서 rhs가 null 인 경우를 대비하여 널 포인터 예외가 발생합니다.

두 번째 세트의 경우와 다른 Null 케이스를 올바르게 처리 할 때 첫 번째 코드 세트가 실제로 정확합니다.

두 조건을 모두 평가하고 단락 회로 동작을 원하지 않는 경우 '|' '||'대신 연산자를 사용하십시오.

따라서 (A | B)의 경우 --- A가 true 일지라도 B가 평가됩니다.