[String] equals 메서드와 == 연산의 차이

2021. 8. 19. 23:51Programming Language/Java

== 연산은 두 String 객체의 주소값이 같은지만 확인을 하는데 반해,
equal 메서드는 스트링 객체의 값이 같은지 확인한다.
해시 코드 값이 다르더라도, 값이 같다면 true를 리턴한다.

 

 

들어가며

 

자바의 모든 객체는 object 클래스를 상속 받으며, object 클래스 내에선 equals 메서드가 있어 두 객체가 같은지 확인할 수 있다.

이 equals 메서드 내에선 기본적으로 hashCode() 메서드로 두 객체의 해쉬코드 값이 같은지를 확인한다.

한편 String 클래스에서는 이 equals 메서드를 오버라이딩하는데, 이 오버라이딩 된 String 클래스의 equals 메서드는 내부적으로 hashCode() 메서드로 해쉬 코드를 비교하는 작업을 하는지 궁금해졌다.

 


 

객체 사이의 == 연산

기본적으로 두 객체 간 == 연산을 수행할 시 객체 값을 비교하는게 아닌, 객체들의 메모리 주소를 비교하여 주소가 같을 시 true, 아니면 false 를 반환한다. 

이 코드에서는 nickName과 name 변수에 각각 "Lee"를 할당했지만, 각자 생성된 힙에서의 주소가 달라 == 연산 시 false 를 출력한다.

 

String 에서는 두 객체의 해시코드 값을 직접 확인할 시 hash() 메서드를 사용해서 보는 것 보다는 System.identityHashCode 메서드로 확인하는게 좋은데, 그 이유는 다음의 블로그(https://codechacha.com/ko/java-system-identityhashcode/)에 친절히 설명되어 있다. 간단히 설명하자면, String 클래스에서는 hashCode() 메서드를 오버라이딩해서 String 객체 주소가 달라도 값이 같을 시 동일한 해시코드 값을 리턴하도록 구현되어 있기 때문이다. 하지만 identityHashCode()는 그런거 없고 객체의 찐 해시코드 값을 리턴한다.

 


 

String 객체의 equals() 메서드

 

오버라이딩 된 equals 메서드를 살펴보자.

 

제일 먼저 첫번째 if 문에서 두 객체 간 == 연산을 수행한다. 해시코드 값이 같다면, 바로 true를 리턴한다. 해시코드 값이 다르다면, 다음 if문으로 넘어간다.

다음 if문에선 비교를 위해 들어온 객체가 먼저 String 클래스의 객체인지 확인 후 String 객체로 형변환한다. 이후 인코딩 타입 확인 후 StringLatin1 클래스 내의 equals로 두 객체의 string value값(바이드 배열)이 넘어가게 된다. 이 equals 메서드에서는 for 문을 돌면서 인자로 들어온 두 string value 값을 비교하는데, 자세한 코드는 다음과 같다.

 

 

즉, 두 스트링 객체의 해시코드 값이 달라도 바이트 배열 값이 동일하다면, 같은 string 이라고 간주한다.

 

 

요약하면,

 

equals 메서드는 두 String 객체가 다른 객체여도 string 값이 동일하다면 true 를 리턴하지만,

== 연산의 경우엔 두 객체의 해시코드 값이 다르기 때문에 false 를 리턴한다.

 

 

디버거 모드를 사용하여 메서드들을 타고 들어가면서 값을 확인하면, 보다 자세한 실행 흐름을 확인할 수 있다.

전체 코드.

 

String.equals() 메서드 확인

 

StringLatin1.equals() 메서드 확인

 

 

'Programming Language > Java' 카테고리의 다른 글

JVM의 Garbage Collection 과정  (0) 2021.08.20
자바의 스택 / 프레임 구조  (0) 2021.08.13
자바의 접근 제어자  (0) 2021.08.11
자바의 참조 변수(Reference Type)  (0) 2021.08.10
배열  (0) 2021.08.08