이번엔 equals에대한 내용이다. 

 

"==" 으로 연산하는 "동일성" 은 두개의 객체가 참조주소가 동일한 객체를 가리키고 있는지를 본다. 즉, 같은주소에 데이터를 가르킨다면 값또한 같을꺼다.

"equals()"메서드를 사용한다면, 주소가 같은게아닌 해당 객체가 논리적으로 동일한지를 확인한다.. 즉 주소는 달라도 값이 동일하면OK.

 

 

public class UserV1 {
    //String 타입 id1 선언
    private String id1;

    //생성자를 통해서 id1을 전달받음
    public UserV1(String id1){
        this.id1 = id1;
    }
}
public class EqualsMainV1 {

    public static void main(String[] args) {
        // user1,user2로 같은 값을 인스턴스 생성
        UserV1 user1 = new UserV1("id-100");
        UserV1 user2 = new UserV1("id-100");

        // == 과 equals를 사용하여 결과를 비교
        System.out.println("Identity = " + (user1 == user2));
        System.out.println("Equality = " + (user1.equals(user2)));
    }
}

"=="의 경우 두개의 생성자로인해 주소값이 다를테니 당연히 false가 맞을테고,

equals()경우 같은 값인지만 볼텐데 false가 나오는건....

equals의 또 내부적인 코드가... 아래와 같기때문이라고 한다..

 

Object클래스의 내부

내부적인 코드에 ==가 있으니...결국은 false..라는건데

 

위 코드를 오버라이딩 한다. 

public class UserV2 { //다른샘플 
    private String id;

    public UserV2(String id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object obj) { //overriding 한다.
        UserV2 user = (UserV2) obj;  //UserV2 타입의 user에 Object클래스의 obj를 다운캐스팅한다.
        return id.equals(user.id);  //값을 전달받은 id를 equals 처리한다.
    }
}

 

 

처리하면 실행결과는  원했던 결과를 도출할 수 있다. 

오버라이딩 결과

 

 

 

챗 지피티를 통해서 확인해보니 오버라이딩은..아래와 같이 하는게 정석이라고 하며 결과가 운이 좋아서 나온거라고 했다...

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;                     // 동일성 체크
    if (obj == null || getClass() != obj.getClass()) return false;

    UserV1 user = (UserV1) obj;
    return this.Id1.equals(user.Id1);                 // value 비교
}

내용을 보니  전달받은 객체가 동일하면 묻지도 따지지도말고 true를 반환하고... 

obj 가 null이면 안되고, getClass()  ! = obj.getClass() 이면 (클래스정보가 이미 틀리면) false를 반환하라고 되어있다.

나머지는 다운캐스팅해서 equals하는건동일한데....

솔직히 이해가 되질않았다.

 

질문  :
잠깐 public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false;

  1. 이코드는 너가말한 의미라면 오버라이딩된후 this == obj 면 true. 즉 오버라이딩하면 true(동등) 이 확인될꺼다
  2. obj ==null. 널 값이거나, 클래스가 완전다르면 비교할 필요가 없다 .. 라는건데 결과적으로 내가 너한테 처음문의한것이 , 같은 클래스의 같은 값을 인스턴스만 2개로 분리해서 비교한건데,,,, 굳이 이 결과를 비교할 필요가있어 ?

 

✅  equals는 “계약을 지키기 위한 공식 구조”로 짜야 해

자바에서는 equals()는 Object 클래스의 명세(contract)를 따르도록 되어 있어:

equals()는 다음 조건을 반드시 지켜야 한다:

  • 반사성(reflexive): x.equals(x)는 true
  • 대칭성(symmetric): x.equals(y)이면 y.equals(x)
  • 추이성(transitive): x==y, y==z → x==z
  • 일관성(consistency): 값이 변하지 않으면 결과도 변하지 않음
  • null 비교 시 false 반환

✔ 이 계약을 깔끔히 지키려면:
==, null, getClass() 같은 체크는 반드시 들어가는 게 관례야.

관례를 물어본게 아니고...오버라이딩을 해야 값이 정상적으로 나오는건지, [ if (this == obj) return true;] 요 값때문에 정상을 나온다는건지가 궁금했던거고...애초에 내가 짠 코드에선  "==" 는 존재하지도 않았기에 지피티가 오답을 준거 같았다...

 

재질의 
자자.... 너 자꾸 말이 딴데로 새어나간다 ㅠㅠ
"id-100".equals("id-100") → true 이말인즉슨 결국 오버라이딩 안해도
논리적으로는 true 가 나와야지..

public boolean equals(Object obj) {
UserV2 user = (UserV2) obj;
return id.equals(user.id);

이 코드는 qeuals(Object obj). >> Object 클래스의 이퀄 메서드를 obj에 받고 UserV2 타입의 user에 위의 obj를 다운캐스팅해서 대입하란거잖아
마지막으로 그 결과를 return 하는거고
즉..즉..그냥 이퀄을 쓴거야 ,
나머지 구구절절한 코드는 오버라이딩의 작업일 뿐이고, 오버라이딩 안하면 equals는 false인데, 오버라이딩을 하면 true라는 말인거자나

내가 물어보는 핵심은 toString처럼 동적 바인딩 같은 시스템이 기저에 깔려있냐는거야

 

 

그제서야 답변을 다시해준다...

✅ 결론부터 말할게:

예, 맞아. equals()도 toString()과 똑같이 "동적 바인딩" 위에서 작동한다.
즉, 오버라이딩하면 실행 시점에 자식 클래스의 equals()가 호출된다.

 

그러니깐 너가말한 equals의 내부적인 == 때문에 발생된 일이기는 하고...
그 기저에는 동일한 연산을하더라도 오버라이딩을 하면 true로 연산되도록 동적 바인딩이 작업해준다 이거지 ?
또 if == ... true 말하지말고

✅ 네 말이 딱 맞다

같은 equals() 호출이더라도,
오버라이딩을 하면 JVM이 동적 바인딩을 통해
"내가 새로 정의한 equals() 메서드"를 실행해준다.

  • 그래서 동일한 연산 (a.equals(b))을 해도
  • 오버라이딩 여부에 따라 결과가 다르게 나오는 것
  • 이건 동적 바인딩(다형성)의 결과지, 단순 코드 트릭이 아님

 

 

빙글 빙글 돌아서 동적 바인딩으로 인한 결과라는 답을 얻었다.

AI를 너무 믿지 말자..

 

'Java_library > Object 클래스' 카테고리의 다른 글

(Java_library) Object.toString()  (0) 2025.05.01
Object 클래스 - 최상위 클래스  (0) 2025.05.01

+ Recent posts