Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

forDevLife

[java] hashCode(), toString(), equals() 본문

Java

[java] hashCode(), toString(), equals()

JH_Lucid 2021. 6. 2. 00:01

1. hashCode()

- 객체의 해시 코드를 반환하는 메서드

- Object 클래스의 hashCode()는 객체의 주소를 int로 변환해서(만들어서) 반환

 

public class Object {
	...
    public native int hashCode();

 

-> native 메서드(OS가 가지고 있는 메서드 - 주로 c로 작성)

-> 내용이 없음. 이미 작성되어있는 메서드를 사용함. 내용을 볼 수가 없다.

-> 객체마다 항상 다른 값이 나온다 = 객체의 지문

 

- equals() (->  iv)로 작업를 오버라이딩 하면, hashCode()도 오버라이딩해야 함. -> 둘 다 객체 주소로 작업

- equals의 결과가 true인 두 객체의 해시코드는 같아야 하기 때문!

 

+ 참고 :  System.identity.HashCode(Object obj)는 Object 클래스의 hashCode()와 동일하게 객체의 주소값으로 해시코드 생성

    -> String 클래스는 문자열 내용 같으면 동일한 해시코드 반환. 하지만 System~ 이거 이용하면 항상 다른 해시코드값 반환을 보장함

 

+ 32bit JVM : native int 

   64bit JVM : 8byte -> int 이므로, 주소값이 겹쳐 hashCode가 겹칠 수 있다.

+ 해싱 기법 사용하는 HashMap, HashSet 같은 클래스에 저장할 객체는 반드시 HashCode 메서드 오버라이딩 해야한다.

 


2. toString()

- 객체를 문자열(String)으로 변환하기 위한 메서드, 더 쓸모있는 정보를 제공할 수 있다.

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

- getClass() : 설계도 객체 // 클래스 생성되면 Class 클래스도 함께 생성된다. getClass()는 이 Class를 get 하는 메서드이다.

- getName() : 클래스 이름

- @ : 위치(at)

- Integer.toHexString : 16진 문자열로 바꿔서 출력

- hashCode() : 객체 주소를 int로 바꿈

 

 

package com;

class Card{
    String kind;
    int number;

    Card() {
        this("SPADE", 1);
    }

    public Card(String kind, int number) {
        this.kind = kind;
        this.number = number;
    }
}

public class Ex14_0 {
    public static void main(String[] args) {
        System.out.println(new Card().toString());
        System.out.println(new Card().toString());

        Card card = new Card("king", 2);
        System.out.println(card.toString());
    }
}

toString 오버라이딩 전

- 클래스이름@객체 hashCode 순서로 출력이 된다.

 

 

toString 오버라이딩 후

- 객체는 iv(instance 변수) 집합 -> iv 값들을 문자열 결합으로 변경할 수 있다.

 


3. equals()

- String class 등은 Object 클래스의 equals 메서드를 그대로 사용하는게 아니라, 문자열 값을 비교하도록 오버라이딩 되어있다.

- 따라서 문자열.equals()로 비교가 가능한 것이다.

- StringBuffer클래스는 오버라이딩 되어있지 않다.

 

- 앞서 살펴본 것처럼, 클래스의 iv로 객체의 같고 다름을 판단할 경우, equals 및 hashCode를 둘 다 오버라이딩 해야한다고 했다.

- 같은 객체라면, hashCode 메서드를 호출했을 때의 결과값인 해시코드도 같아야하기 때문이다.

- hashCode 오버라이딩 하지 않는다면, Object 클래스에 정의된 대로 모든 객체가 서로 다른 해시코드 값을 가질 것이다.

 

 


4. getClass()

- 이 메서드는 자신이 속한 클래스의 Class 객체를 반환하는 메서드이다.

- 'Class' 객체는 이름이 'Class'인 객체이다. 아래와 같이 정의되어 있다.

public final class Class implements... { //Class 클래스

 

 

- Class 객체는 클래스의 모든 정보를 담고 있으며, 클래스 당 1개만 존재한다. 설계도 객체라고 한다.

- 이를 통해, 객체 생성, 정보 습득 가능하다.

- 동적으로 객체 생성 & 메서드 호출 하는 방법을 'ReflectionAPI' 라고 한다. 

- 클래스 파일이 '클래스 로더'에 의해서 메모리에 올라갈 때 자동으로 생성된다.

   * 클래스 로더 : 실행시에 필요한 클래스를 동적으로 메모리에 로드하는 역할

       -> 기존에 생성된 클래스 객체가 메모리에 존재하는지 확인

       -> 있으면 객체의 참조를 반환 / 없으면 클래스 패스에 지정된 경로를 따라서 클래스 파일을 찾는다.

       -> 못 찾으면 ClassNotFoundException 발생, 찾으면 해당 클래스 파일 읽어서 Class 객체로 변환한다.

 

- 정리하자면, 파일 형태로 저장되어 있는 클래스를 읽어서 Class 클래스에 정의된 형식으로 변환하는 것이다. 

 

 

- Class 객체를 얻는 방법

Class cObj = new Card().getClass(); // 생성된 객체로부터 얻기
Class cObj = Card.class();          // 클래스 리터럴(*.class)로 부터 얻는 방법
Class cObj = Class.forName("Card"); // 클래스 이름으로 부터 얻는 방법
Card c = new Card();                // new 연산자로 객체 생성
Card c = Card.class.newInstance();  // Class 객체를 이용해서 객체 생성

 

- c1, c2를 출력하면 오버라이딩 된 toString이 출력된다.

- cObj에 getClass를 통해 'Class' 클래스의 객체를 전달한다.

- getName() : 클래스 이름만 출력(class com.Card에서 com.Card만 출력)

- getClass() : 어쨌든 'Class' 클래스도 클래스이니, 얘의 정보를 출력한다. (class java.lang.Class)

- toGenericString() : Card 클래스의 추가 정보를 알려주는 듯?(final도 출력해줌)

- toString() : cObj만 출력하는 것과 동일하다.(당연) 

Comments