개발 공부/자바

모든 클래스의 조상: Object 클래스 핵심 정리

baby-t 2025. 12. 3. 08:37

Java로 개발을 하다 보면 우리가 만든 클래스(Member, Product 등)에서 별도로 정의하지 않은 메소드(toString(), equals() 등)를 자연스럽게 사용하곤 합니다. 이 메소드들은 도대체 어디서 온 걸까요?

바로 Java의 모든 클래스가 묵시적으로 상속받는 최상위 부모, java.lang.Object 클래스 덕분입니다. 이번 포스팅에서는 Java 개발자라면 반드시 알아야 할 Object 클래스의 핵심 기능과, 실무에서 자주 오버라이딩(재정의)해서 사용하는 주요 메소드 3대장(toString, equals, hashCode)에 대해 알아보겠습니다. 👑


## 1. Object 클래스란?

  • 정의: 자바의 모든 클래스의 최상위 부모 클래스입니다.
  • 특징:
    • 우리가 class Member {}라고만 적어도, 컴파일러는 자동으로 class Member extends Object {}라고 처리합니다.
    • 따라서 자바의 모든 객체는 Object 클래스에 정의된 메소드를 사용할 수 있습니다.
  • 목적: 모든 객체가 공통적으로 가져야 할 필수적인 기능(식별, 문자열 표현 등)을 표준화하기 위함입니다.

## 2. 필수 오버라이딩 메소드 3대장

Object 클래스가 제공하는 11개의 메소드 중, 개발자가 자주 재정의하여 사용하는 가장 중요한 3가지를 살펴보겠습니다.

### 1) toString(): 객체를 문자로 표현하기

  • 기본 동작: 클래스명@해시코드(16진수)를 반환합니다. (예: Member@4e50df2e)
  • 사용 이유: 객체의 상태(필드 값)를 사람이 읽기 쉬운 문자열로 확인하고 싶을 때 사용합니다. 주로 로그를 찍거나 디버깅할 때 필수적입니다.

[재정의 전]

Java
 
Member member = new Member("홍길동");
System.out.println(member); // 출력: com.example.Member@4e50df2e (알아보기 힘듦)

[재정의 후]

Java
 
@Override
public String toString() {
    return "Member{name='" + name + "'}";
}

// ...
System.out.println(member); // 출력: Member{name='홍길동'} (명확함!)

### 2) equals(): 객체의 '같음' 비교하기 (중요!)

이 메소드는 기술 면접에서도 단골 질문입니다. **동일성(Identity)**과 **동등성(Equality)**의 차이를 이해해야 합니다.

  • 기본 동작 (==): 두 객체의 **주소 값(참조값)**이 같은지 비교합니다. (물리적으로 같은 객체인가?)
  • 재정의 목적: 주소 값이 다르더라도, 객체가 가진 내용(값)이 같으면 같은 객체로 취급하기 위함입니다. (논리적으로 같은 객체인가?)

예시: 주민등록번호가 같은 두 사람(Person 객체)이 있다면, 서로 다른 메모리 주소에 생성되었더라도 논리적으로는 '같은 사람'으로 봐야 합니다.

Java
 
@Override
public boolean equals(Object o) {
    if (this == o) return true; // 주소가 같으면 무조건 true
    if (o == null || getClass() != o.getClass()) return false; // 타입이 다르면 false
    Member member = (Member) o;
    // 이름(내용)이 같으면 true 반환
    return Objects.equals(name, member.name);
}

### 3) hashCode(): 객체의 지문 (feat. HashMap)

  • 기본 동작: 객체의 메모리 주소를 기반으로 생성된 정수 값을 반환합니다.
  • 재정의 목적: HashMap이나 HashSet 같은 해시 기반 컬렉션에서 객체를 올바르게 구분하기 위함입니다.

⚠️ 매우 중요한 규칙 (The Contract)

equals()를 재정의했다면, 반드시 hashCode()도 재정의해야 합니다.

논리적으로 같은 객체(equals가 true)라면, 해시코드(hashCode)도 반드시 같아야 하기 때문입니다. 만약 이를 어기면, HashSet에 데이터를 넣었는데 contains()로 찾지 못하는 버그가 발생합니다.

 


## 3. 그 외의 주요 메소드들

자주 오버라이딩하지는 않지만, 알아두면 좋은 메소드들입니다.

  • getClass(): 객체의 클래스 정보(설계도)를 반환합니다. 리플렉션(Reflection) 기술의 시작점이 됩니다.
  • clone(): 객체의 복사본을 생성합니다. (하지만 사용이 까다로워 실무에서는 직접 구현하기보다 생성자 복사 등을 권장합니다.)
  • wait(), notify(), notifyAll(): 스레드(Thread) 동기화를 위해 사용됩니다. 특정 조건이 충족될 때까지 스레드를 잠시 멈추거나 깨우는 역할을 합니다.

## 4. 요약 정리

메소드 기본 동작 재정의(Override) 목적
toString() 클래스명@해시코드 반환 객체의 정보를 문자열로 쉽게 확인하기 위해
equals() == (주소 비교) 객체의 내용(값)이 같은지 비교하기 위해
hashCode() 주소 기반 정수 반환 HashMap 등에서 객체를 식별하기 위해 (equals와 짝꿍)

Object 클래스는 Java의 시작점이자, 모든 객체가 지켜야 할 기본 규칙을 담고 있습니다. 특히 equals와 hashCode는 데이터의 정확성을 위해 반드시 올바르게 재정의해서 사용해야 합니다. (다행히 IntelliJ 같은 IDE나 Lombok 라이브러리가 자동 생성을 도와줍니다!)

'개발 공부 > 자바' 카테고리의 다른 글

자바 공부 일지 (기초)  (0) 2026.02.16
자바 공부 일지 (면접 질문 위주)  (0) 2026.02.16
Java의 다형성 완전 정복  (0) 2025.09.25
자바 면접 질문2  (0) 2025.09.24
자바 면접 질문1  (0) 2025.09.24