Object 클래스 메서드 (equals(), hashCode(), toString())

초코칩·2023년 2월 12일
1

Java

목록 보기
1/14
post-thumbnail

동일성(identity), 동등성(equality) 비교

객체의 비교는 두 가지 방법이 존재한다. 바로 동일성과 동등성이다.

동일성(identity)

동일성은 두 인스턴스가 같은 존재인지 판단하는 것이다. 동일성 비교는 == 연산자를 이용해서 객체 인스턴스 주소 값을 비교한다. 기본적으로 Object의 equals() 메서드는 동일성(==) 비교로 작동한다.

동등성(equality)

동등성은 두 인스턴스 값이 같은지 확인하는 것이다. 동등성 비교는 equals() 메서드를 Overriding해서 객체 내부의 값을 비교하여 구현할 수 있다.

Example

아래 예시에서 확인하자.

public class Main {
    public static void main(String[] args) throws Exception {
        
        // 두 객체 인스턴스 생성
        String s1 = new String("test");
        String s2 = new String("test");

        // 동일성 비교
        System.out.println(s1==s2);

        // 동등성 비교
        System.out.println(s1.equals(s2));
    }
}
Result: false
Result: true

문자열 s1, s2를 생성하고 "test"로 생성한다. Java에서 String 객체는 Immutable이기에 Heap 영역에 메모리가 할당된다. s1s2는 같은 값을 가지고 있으면서도, 다른 주소값을 가지는 것이다.

동일성(identity)을 통해 비교할 경우 다른 주소 값을 가지기에 false가 출력된다. 반면, 동등성(equality)을 통해 비교를 할 경우 true가 출력되는 것을 알 수 있다. 이를 통해 단순히 값을 비교해야 할 경우, equals()를 통해 비교해야 정확한 비교가 가능해진다. (주소값까지 비교하고 싶을 사람은 없을테니...?)

Immutable
new 연산자로 heap 영역에 객체가 생기고 래퍼런스 값을 가지는 변수가 stack에 생긴다. immutable은 이 객체의 값을 heap영역에서 바꿀 수 없는 불변 객체이다.

equals와 indexOf의 관계

indexOf는 객체를 찾을 때 equals 메서드를 사용하여 객체의 동등성을 비교한다. 즉, List나 String에서 indexOf를 호출하면, 내부적으로 equals 메서드를 호출하여 객체를 찾는다.

예를 들어, list.indexOf(someObject)는 someObject와 list의 각 요소를 equals 메서드로 비교하여 해당 객체의 인덱스를 반환한다.

객체 해시코드(hashCode)

객체 해시코드란 객체를 식별하는 정수를 의미한다. Object의 hashCode() 메서드는 객체의 메모리 번지를 이용해서 해시코드를 생성하기 때문에 객체마다 다른 정수값을 반환한다. hashCode() 메서드의 용도는 equals() 메서드와 비슷하게 동등성을 비교할 때 주로 사용한다.

Example

public class Main {
    public static void main(String[] args) throws Exception {
        // 객체 인스턴스 생성
        Test test = new Test();

        // 해시코드 출력
        System.out.println(test.hashCode());
    }
}

class Test{
	private int number;
    private String name;
    Test(){
    	number = 12;
        name = "Chocochip";
	}
}
Result: 622488023

객체 문자 정보(toString)

Object의 toString() 메서드는 객체의 문자 정보를 반환한다. 이때 객체의 문자 정보란 객체를 문자열로 표현한 값을 말한다. 기본적으로 Object의 toString() 메서드는 클래스명@16진수해시코드로 구성된 문자열을 반환한다.

용도

그러면 이러한 toString() 메서드는 언제 Overriding해서 사용할까? 모든 클래스의 toString()을 Overriding할 필요는 없다. 하지만 디버깅이 필요한 경우(비즈니즈 로직), 객체의 정보를 확인할 수 있기 때문에 이런 경우는 Overriding하는게 좋다.

Example

public class Main {
    public static void main(String[] args) throws Exception {
        // 객체 인스턴스 생성
        Test test = new Test();

        // 문자정보 출력
        System.out.println(test.toString());
    }
}

class Test{
	private int number;
    private String name;
    Test(){
    	number = 12;
        name = "Chocochip";
	}
}
Result: Test@251a69d7

toString() 오버라이딩

객체의 문자정보를 해시코드 대신 다른 정보를 전달하고 싶을 경우에는 Object의 toString() 메서드를 오버라이딩하여 유익한 정보를 리턴하도록 해야한다.

public class Main {
    public static void main(String[] args) throws Exception {
        // 객체 인스턴스 생성
        Test test = new Test();

        // 문자정보 출력
        System.out.println(test.toString());
    }
}

class Test{
	private int number;
    private String name;
    Test(){
    	number = 12;
        name = "Chocochip";
	}
    
    
    @Override
    public String toString() {
        return number + ", " + name;
    }
}
Result: 12, Chocochip
profile
초코칩처럼 달콤한 코드를 짜자

0개의 댓글