본문 바로가기

프로그래밍/Java

equals() 와 ==

반응형

해당 포스트의 작성 목적

equals()의 메소드와 == 으로 비교시에 대한 명확한 차이점을 알고, 왜 그렇게 써야하는지에 대해 알아본다.


==

==은 동등비교연산자로, 기본 자료형 변수들에 한해서, 변수의 값을 비교하고, 같으면 true, 다르면 false를 출력한다.

그렇기 때문에, 참조형 객체의 값을 비교할때는 == 을 쓰는것에 유의해야 한다.

단, String의 경우 리터럴 생성시와 new연산자 생성시에 따라 사용 가능할때가 있다.

new연산자로 생성시 값이 같아도, 객체의 주소값은 다른 또다른 객체가 힙메모리에 생기기 때문에, 동등비교연산자로 비교해도 값은 무조건 다르다고 나온다.

그러나 리터럴 생성시, 힙메모리의 StringPool이라는 공간에 객체가 생성되고, 이후 StringPool에 있는 값과 같은 String 객체를 리터럴로 생성하거나 비교시 새로운 String 객체를 생성하지 않고, StringPool에 있는 객체의 주소를 리턴해준다. 즉, 같은 객체의 주소를 가리키므로, == 동등비교연산자를 사용해도 문제가 없다.

equals()

equals()메소드는 object클래스에 정의된 메소드로, object클래스에서 정의된 것은 매개변수와 메소드를 사용한 객체가 기본자료형이라면 값을, 참조자료형이라면 hascode()값(주소값을 해시한 코드)을 비교하고, 같으면 true, 다르면 false를 출력하는 메소드다.

그렇다면 위의 == 동등비교연산자와의 다른점은 무엇일까??

모든 클래스는 Object를 상속받는다. 그러므로 equals()메소드도 상속을 받는다. 또한, Java에서 정의된 클래스들은 이 메소드를 각 클래스에 맞춰 오버라이드 한다는 것에 있다.

즉, 참조형 객체안의 변수들의 값을 포함해서 서로 비교하도록 오버라이드를 하게된다.

이때 중요한 점이있다. 값을 비교해서 true로 반환해도, 두 객체의 hashCode()값 (주소값을 해시한 코드)은 다른 상태라는 것이다. 이는 해당 객체들이 HashCollection에 들어갈 경우 오류가 날수있기 때문에, equals()메소드를 오버라이드 할때는 반드시 hashCode() 메소드도 함께 오버라이드 해줘야 한다.

hashCode()

hashCode()는 객체가 존재하는 메모리의 주소값을 Hash한 코드로 (주소값이 아니다!...)알고리즘의 한계로인해, 다른객체라도 같은 hashCode가 나올수 있다. 매우 적은 확률로... 그렇기때문에, hashCode()값이 같다고 해서 반드시 두 객체가 같다는 보장은 할수없다.

여기서 주의해야할 점이 있는데, String의 경우 hashCode()메소드가 재정의 되어있다.

s[0]*31^(n - 1) + s[1]*31^(n - 2) + ... + s[n - 1]

String은 char의 배열형태로, 위의 배열인엑스 0번의 값부터 마지막까지 일정 상수를 곱해준다.

그런데 여기서 문제가있다. char배열의 char는 숫자로 변환될때 아스키코드값으로 변환되며, 이는 이미 정의되어진 값들이다. 즉, 자바 애플리케이션을 종료후 재시작해도, 이 hashCode()의 값은 같게 나온며, String은 문자열의 값이 같으면 다른 객체라 할지라도 hashCode의 값이 같게 나온다는 것을 알 수 있다.

해당 포스트 작성으로 알게된점

대략적으로 equals()메소드와 == 연산자의 차이를 알고는 있었지만, hashCode() 메소드의 중요도까지 생각은 못했었다. 또, hashCode()메소드가 당연히 주소값 그자체를 반환하는줄 알았는데, 주소값을 hash한 값을 반환하는것으로 그 둘은 명백한 차이가 있다는 것을 알게되었다.

특히 String클래스의 hashCode()의 경우 char[]의 각 요소에 특정 상수를 곱하고, 각 원소는 아스키코드로 변환되며, 만일 서로다른 두 String객체라 할지라도, 값이 같다면 같은 hashCode()를 반환한다는 것을 깨달았다. 이러한 이유로 참조자료형은 특히 String 클래스는 반드시 == 연산자가 아닌, equals()메소드를 통해 비교해야 같은 객체임을 판별할수 있다는 것을 알게되었다.


References

반응형

'프로그래밍 > Java' 카테고리의 다른 글

JVM이란 무엇인가  (0) 2021.05.13
String의 == 연산시 동작  (0) 2021.05.13
Buffer VS Cache  (0) 2021.05.12
캐시는 어느영역에서 사용되나?  (0) 2021.05.11
캐시(Cache)란?  (0) 2021.05.11