코딩.zip

[Java] Object class - toString(), equals() 메서드 본문

프로그래밍/Java

[Java] Object class - toString(), equals() 메서드

김주짱 2024. 6. 1. 16:14

 

java.lang 패키지

가장 기본으로 제공해주는 라이브러리

lang은 language의 줄임말, 자바의 기본이 되는 클래스들을 보관하는 패키지

import 구문 사용하지 않아도 자동으로 임포트된다. 

 

java.lang 대표적인 클래스

  • Object : 모든 자바 객체의 부모 클래스 (최상위 클래스) 따라서 모든 객체를 참조할 수 있다!
  • String : 문자열
  • Integer , Long , Double : 래퍼 타입, 기본형 데이터 타입을 객체로 만든 것
  • Class : 클래스 메타 정보
  • System : 시스템과 관련된 기본 기능들을 제공

Object Class - 생략 권장

부모가 없으면 묵시적으로 Object(java.lang) 클래스를 상속 받음

 

Object 는 모든 객체에 필요한 공통 기능을 제공한다. `

Object 는 최상위 부모 클래스이기 때문에 모든 객체는 공통 기능을 편리하게 제공(상속) 받을 수 있다.

 

Object가 제공하는 기능은 다음과 같다.

  • 객체의 정보를 제공하는 `toString()` - 객체를 문자열로 반환
  • 객체의 같음을 비교하는 `equals()`
  • 객체의 클래스 정보를 제공하는 `getClass()`
  • 기타 여러가지 기능

Object 다형성

action(Object obj)` 메서드

이 메서드는 `Object` 타입의 매개변수를 사용한다. 그런데 `Object는 모든 객체의 부모. 따라서 어떤 객체든지 인자로 전달할 수 있다. 그러나 Object를 통해 전달 받은 객체를 호출하려면 각 객체에 맞는 다운캐스팅 과정이 필요하다. Object가 세상의 모든 메서드를 알고 있는 것이 아니기 떄문에 다형적 참조 + 메서드 오버라이딩을 함께 사용하기가 어렵다. 왜(why)?  다형성 참조만 가능하므로

 

그럼 언제(when) Object를 활용하는 것이 좋을까?

➡️ Object 배열 : Object[]을 만들면 세상의 모든 객체를 담을 수 있는 배열을 만들 수 있다.

package lang.object.poly;

public class ObjectPolyExample2 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Car car = new Car();
        Object object = new Object();

        Object[] objects = {dog, car, object};

        size(objects);
    }

    private static void size(Object[] objects) {
        System.out.println("전달된 객체의 수는: " + objects.length);
    }
}

Object는 모든 객체를 담을 수 있기 때문에  size() 메서드는 어디서든 사용 가능해진다.

 

다형적 참조: `print(Object obj)` , `Object` 타입을 매개변수로 사용해서 다형적 참조를 사용한다. `Car` , `Dog` 인스턴스를 포함한 세상의 모든 객체 인스턴스를 인수로 받을 수 있다.


메서드 오버라이딩: `Object` 는 모든 클래스의 부모이다. 따라서 `Dog` , `Car` 와 같은 구체적인 클래스는 Object` 가 가지고 있는 toString()` 메서드를 오버라이딩 할 수 있다. 따라서 `print(Object obj)` 메서드는 `Dog` , `Car` 와 같은 구체적인 타입에 의존(사용)하지 않고, 추상적인 `Object` 타입에 의존하면서 런타임에 각 인스턴스의 toString()` 을 호출할 수 있다.

 

toString() 메서드

객체의 정보를 문자열 형태로 제공한다. 그래서 디버깅과 로깅에 유용하게 사용된다.
이 메서드는 `Object`클래스에 정의되므로 모든 클래스에서 상속받아 사용할 수 있다.

 

Object.toString() 소스

public String toString() {
          return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

 

자바 프레임워크와 API는 toString 메서드를 자동으로 호출한다.

예를 들어, System.out.println(object)를 호출하면 내부적으로 object.toString()이 호출된다.

equals() 메서드

객체의 동등성 비교를 제공한다. 

자바는 두 객체가 같다라는 표현을 2가지로 분리해서 제공한다.

**동일성(Identity)**: `==` 연산자를 사용해서 두 객체의 참조가 동일한 객체를 가리키고 있는지 확인

**동등성(Equality)**: `equals()` 메서드를 사용하여 두 객체가 논리적으로 동등한지 확인

 

동등성이라는 개념은 각각의 클래스 마다 다르다. 
어떤 클래스는 주민등록번호를 기반으로 동등성을 처리할 수 있고, 
어떤 클래스는 고객의 연락처를 기반으로 동등성을 처리할 수 있다. 
어떤 클래스는 회원 번호를 기반으로 동등성을 처리할 수 있다.
따라서 동등성 비교를 사용하고 싶으면 `equals()` 메서드를 재정의해야 한다. 
그렇지 않으면 `Object` 는 동일성 비교를 기본으로 제공

 

package lang.object.equals;

public class UserV1 {

    private String id;

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

package lang.object.equals;

public class EqualsMainV1{

    public static void main(String[] args) {
        UserV1 user1 = new UserV1("id-100");
        UserV1 user2 = new UserV1("id-100");

        System.out.println("identity = " + (user1==user2)); //false
        System.out.println("equality = " + (user1.equals(user2))); //false
    }
}

 

동등성 비교를 위해 equals()` 메서드를 재정의

package lang.object.equals;

public class UserV2 {

    private String id;

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

//  동등성 비교를 위한 equals() 재정의
    @Override
    public boolean equals(Object obj) {
//      Object obj = new UserV2(); // obj는 UserV2 객체를 참조하고 있음
        UserV2 user = (UserV2) obj; // obj를 UserV2 타입으로 형변환(다운캐스팅) -> obj에 id가 없기 때문에
        boolean result = id.equals(user.id); // 문자열 비교는 `==` 이 아니라 `equals()` 를 사용
        return result;

    }
}


package lang.object.equals;

public class EqualsMainV2 {
    public static void main(String[] args) {
        UserV2 user1 = new UserV2("id-100");
        UserV2 user2 = new UserV2("id-100");

        System.out.println("identity = " + (user1 == user2)); // false
        System.out.println("equality = " + (user1.equals(user2))); // true
    }
}

 

이건 이해를 위해 간단히 만든 ver이다.

정확한 equals() 메서드 구현은 쉽지 않다. (외워서 할 수 없음)

 

 

왜(why) equals 메서드 Objcect 클래스의 메서드인데 매개변수를 받을까?

  • 비교 대상 지정: equals 메서드는 두 객체가 동등한지 비교하는 데 사용되는데 이 비교를 위해서는 현재 객체(this)와 비교할 대상 객체(obj)가 필요하다. 따라서 매개변수를 받아야 한다!

'프로그래밍 > Java' 카테고리의 다른 글

[Java] String, StringBuilder, String 최적화  (0) 2024.06.02
[Java] 불변 객체  (0) 2024.06.01
스프링 MVC STS3, STS4 설치  (0) 2024.05.13
[Java] 컬렉션 프레임워크  (0) 2024.05.02
[Java] 파일 입출력  (2) 2024.04.17