Dev/Java

[Java] Java에서 Wrapper 타입의 비교는 == 연산자 대신 equals()를 사용해야 하는 이유

김세진 2023. 7. 4. 21:37
반응형

 

 

 

개요

 

 개발 중 이슈가 생겨 디버깅을 하던 도중, Long 과 Long 타입을 비교하는 구문에서 서로 두 값이 동일함에도 불구하고 간헐적으로 true가 아닌 false 가 반환되는 현상을 확인하였다. 원인 확인 결과, == 연산자와 equals 의 차이에서 오는 문제였다.

 

 

원인

 

 Java에서 객체 비교는 대표적으로 == 연산자와 equals() 메서드를 사용하여 수행할 수 있다. == 연산자는 객체의 주소값을 비교하기 때문에 같은 값을 가지고 있어도 주소값이 다르다면 false를 반환한다. 단, 위에서 언급했듯 간헐적으로 값을 정상적으로 비교할 수 있었던 이유는 Java에서 Long과 Integer의 경우 값을 -128부터 127까지의 범위에 대해 캐시하고 있기 때문에 동일한 주소의 객체로 인식하기 때문이다. 따라서 아래와 같은 현상이 발생한다.

 

Long a = 127L;
Long b = 127L;
Long c = 128L;
Long d = 128L;

System.out.println(a == b); // true
System.out.println(c == d); // false

System.out.println(a.equals(b)); // true
System.out.println(c.equals(d)); // true

 

해결

 

따라서, long, int 같은 Primitive타입이 아닌 Long, Integer 같은 Wrapper 타입의 값 비교는 ==이 아닌 equals를 사용하여 정확한 값 비교를 수행하도록 하자.

 

추가적으로, a.equals(b) 구문은 null-safe하지 않기 때문에 a와 b에 대한 null 체크가 요구된다. Java 7 부터는 Objects.equals() 를 사용할 수 있는데 해당 메서드의 경우 자체적으로 null 체크를 해주기 때문에 보다 편리한 값 비교가 가능하다. 따라서 Objects.equals(a, b) 와 같은 형태로 사용하는 방식이 가장 권장되는 방식이 되겠다.

 

 

반응형