[JAVA] Object 클래스의 toString(), equals(), hashCode()

4535 단어 JavaJava

Object 클래스

Java Document에서는 Object 클래스를 다음과 같이 정의한다.
Object는 모든 클래스의 최상위 클래스로, 모든 클래스는 Object 클래스를 상속받고 있다.

Object 클래스가 가지고 있는 메소드는 다음과 같다.

  • public boolean equals(Object obj)
  • protected void finalize()
  • public Class<?> getClass()
  • public int hashCode()
  • public void notify()
  • public void notifyAll()
  • public String toString()
  • public void wait()
  • public void wait(long timeout)
  • public void wait(long timeout, int nanos)

모든 클래스는 Object를 상속받는다고 했기 때문에 자바의 모든 객체는 위 메소드를 가지고 있다고 할 수 있다. 이 중에서 자주 사용되는 toString(), equals(), hashCode()를 오늘 중점적으로 살펴보겠다.


toString()

toString()은 객체를 문자열로 표현하는 메소드이다.

디폴트 동작 : getClass().getName() + '@' + Integer.toHexString(hashCode())

해당 메소드는 overriding을 해서 객체의 상태를 쉽게 파악할 수 있게 한다.

// overriding(재정의) 이전

package com.programmers.java;

public class User {
    private int age;
    private String name;

    public User(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public static void main(String[] args) {
        User user = new User(27, "Emily");
        System.out.println(user.toString());
    }
}

-> 실행 결과 : com.programmers.java.User@1dbd16a6

// overriding(재정의) 이후

package com.programmers.java;

public class User {
    private int age;
    private String name;

    public User(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    public static void main(String[] args) {
        User user = new User(27, "Emily");
        System.out.println(user.toString());
    }
}

-> 실행 결과 : User{age=27, name='Emily'}


equals()

equals()는 두 객체가 같은지 다른지 나타내는 메소드이다.

디폴트 동작 : 두 객체가 주소 값이 동일하다면 true를, 다르다면 false를 리턴('==' 연산 결과)

해당 메소드를 override하면 객체가 메모리에서 같은 주소를 갖는 '물리적 동일함' 뿐만 아니라 같은 age의 사용자 객체, 같은 id의 상품 객체와 같이 같은 내용을 갖는 '논리적 동일함'까지 비교할 수 있게 된다.

// overriding(재정의) 이전

package com.programmers.java;

public class User {
    private int age;
    private String name;

    public User(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public static void main(String[] args) {
        User user = new User(27, "Emily");
        User user2 = new User(27, "Emily");
        System.out.println(user.equals(user2));
    }
}

-> 실행 결과 : false

// overriding(재정의) 이후

package com.programmers.java;

public class User {
    int age;
    String name;

    public User(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if(this.age == ((User)o).age && this.name == ((User)o).name)
            return true;
        return false;
    }

    public static void main(String[] args) {
        User user = new User(27, "Emily");
        User user2 = new User(27, "Emily");
        System.out.println(user.equals(user2));
    }
}

-> 실행 결과 : true

일반적으로 이 메소드를 재정의할 때마다 다음으로 설명할 hashCode()도 재정의해서 hashCode()에 대한 일반 계약을 유지할 수 있게 해야한다.


hashCode()

hashCode()는 객체의 고유한 값(해시코드)을 나타내는 메소드이다.

디폴트 동작 : JVM이 부여한 코드 값을 리턴

hashCode()의 일반 계약 중 하나가 'equals() 메소드에 따라 두 개체가 동일한 경우 두 개체 각각에 대해 hashCode() 메소드를 호출하면 동일한 정수 결과가 생성되어야 한다.'는 것이다. 이 말을 다시 풀어 정리하자면...

  • hashCode()를 실행해 나온 해시코드 값이 다르다 -> 다른 객체
  • equals() 실행 값이 true라면 두 객체의 hashCode() 실행 결과도 같다 -> 같은 객체
  • hashCode()를 실행해 나온 해시코드 값이 같을지언정 equals() 실행 결과가 false가 나올 수 있다 -> 다른 객체

위 설명을 바탕으로 그림을 그려 표현하면 아래와 같다.


(참고)

좋은 웹페이지 즐겨찾기