TIL/JAVA

[TIL] 생긴게 똑같으면 같은거 아닌가요?🤔 (동일성 vs 동등성)

Dream COM Ddulut 2024. 11. 21. 23:13

코딩을 하다보면 무언가 서로 비교할 일이 많다. 

'문자열은 .equals()로 비교하세요.'라고 들어와서 지금까지 문자열을 그렇게 비교해왔는데,

정작 '왜 ==은 쓰지 않는 것인지', '==과 .equals()의 차이는 무엇인지' 깊이 있게 공부하지는 못한 것 같다.

 

예전에 ==과 .equals() 에대해 노션에 정리한적이 있는데, 동등성과 동일성에 대해 알게된 지금 다시보니 너무 간략하게 정리한 느낌..! (나 좀 성장 했나..?🥹)

https://www.notion.so/String-equals-vs-129589af8800804c8a5dc92441b5f701?pvs=4

 

지금부터 동등성과 동일성에 대해 정리하면서 ==과 .equals()의 차이에 대해 더 심도있게 알아보자! ✨


[ 동일성 VS 동등성 ]

동일성(Identity): 물리적으로 같은 것.
                             물리적으로 같은 메모리에 있는 객체 인스턴스인지를 기준으로함 (=참조값 비교)
동등성(Equality): 논리적으로 같은 것.
                             사람이 생각하는 논리를 기준으로함 (=값을 비교)  

 

위 설명만 읽어보면 아직도 아리쏭할 것 이다. 

그래서 예시를 준비했다.

 

 

아래 두 권의 책이있다. 

• 책 A 와 B는 제목과 작가가 같다.

만약 누군가 와서 "나 '제인에어'라는 책 좀 빌려줘"라고 했을 때 A책을 빌려준다면,

그 사람이 "이건 제인에어가 아니야!"라고 부정할까?

일반적으로, A책을 빌려주든, B책을 빌려주든 어쨌든 둘다 '제인에어'이기 때문에 무엇을 빌려주든 고맙다고 할 것이다.

 

'논리적으로 같다(동등하다)'는 게 바로 이런 것이다. 형태나 외관 등이 완전히 같지는 않아도 그 가치와 수준이 같다면 동등한 것이다.  

 

 

  반면, 책 A와 B는 표지와 출판사 책의 사이즈 등이 다르다.

'물리적'으로 두 책은 완전히 동일하지 않다. '동일'은 물리적으로 완전히 같음을 의미한다.


 

이제 JAVA의 입장에서 동일성과 동등성을 이해해보자.

이 두 책을 코드로 표현해보면 아래와 같다.

Book bookA=new Book("제인에어", "샬럿 브론테"); //책 A
Book bookB=new Book("제인에어", "샬럿 브론테"); //책 B

 

 

책 A, B는 책 이름과 작가를 기준으로 생각해보면 논리적으로 동등하다. 

하지만 참조형 변수를 보면 두 책은 물리적으로 다른 메모리에 있으므로 동일하지는 않다.

 

즉, 물리적으로 같은 메모리(=참조값이 동일)에 있으면 동일한 것이고, 물리적으로 같은 메모리에 있지 않으면 동일하지 않은 것이다.


[  = =  과  .equals( )  ]

JAVA에서는 동등성과 동일성을 어떻게 확인할까? 🤨

 

JAVA에서는 == 연산자를 통해 두 객체의 참조값을 비교하여 동일성을 확인한다.

아래는 == 연산자를 사용해 두 책의 참조값을 각각 출력하고, 비교한 결과이다.

== 연산자를 사용해 책A와 B의 참조값을 비교
결과

 

위 그림에서 설명했듯이 두 책의 참조값은 다르다. 

또한 == 연산자가 참조값을 비교하기 때문에 동일성 비교 결과 역시 false가 나온다.

 

[결론] ==연산자참조값을 비교한다. JAVA에서는 == 연산자를 사용해 두 객체의 동일성을 확인할 수 있다.


그럼 동등성은 .equals( )로 확인하나요? 🤔

 

음... 이건 .equals( )를 어떻게 오버라이딩하느냐에 따라 다르다. 

 

왜냐하면 Objects 클래스가 제공하는 .equals( )를 자세히 뜯어보면, 역시 ==을 사용하고 있기 때문이다!

결국 .equals( )역시 동일성 비교를 제공한다.

기본적으로 동일성 비교를 제공하는 .euqals()

 

실제로 책 A, B를 .equals() 로 비교해보면 A, B의 참조값을 비교하고 있고, 그렇기 때문에 결과값 역시 false인 것을 확인할 수 있다.

.equals()로 두 책을 비교
결과


그럼 JAVA에서 동등성 비교는 어떻게 하나요? 🥲

 

우리는  .equals( )를 재정의 함으로써 동등성 비교를 할 수 있다!!

 

사실 String, Integer 등은 모두 객체이기 때문에 .equals( )로 비교를 하면 참조값이 비교되는게 맞다.

하지만 JAVA에서는 해당 객체들의 .equals( )를 재정의 해두었기 때문에 참조값이 아닌, 해당 객체들이 가진 값 자체를 비교할 수 있도록 해두었다.

.equals()로 String, Integer 끼리 비교
결과

 

아래 사진에서 재정의 된 String, Integer의 .equals()를 확인할 수 있다.

재정의 된 String의 .equals()
재정의 된 String의 .equals()

 

 


 

 

지금까지 동일성과 동등성, 그리고 ==과 .equals()에 대해 알아보았다.

 

[정리]

1. 동일성: 물리적으로 같음
    동등성: 논리적으로 같음

2. ==동일성을 비교함
3. .equals( )재정의하면 동등성 비교를 할 수 있음