이번엔 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의 또 내부적인 코드가... 아래와 같기때문이라고 한다..

내부적인 코드에 ==가 있으니...결국은 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;
|
✅ 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 |