/ JAVAJUNGSUK

Ch9-4~6. Object 클래스

자바의 정석 기초편

0. 목차



Chapter9. java.lang 패키지와 유용한 클래스

Ch9 - 4. Object 클래스의 메서드 : hashCode()

Ch9 - 5. Object 클래스의 메서드 : toString()

Ch9 - 6. toString()의 오버라이딩



Ch9 - 4. Object 클래스의 메서드 : hashCode()


▶ hashCode()란?

▷ 객체의 hashCode()를 반환하는 메서드
▷ hashCode : 정수 값, 해싱 알고리즘에서 사용
▷ Object 클래스의 hashCode()는 객체의 주소를 int로 변환하여 반환
▷ hashCode() = 객체의 지문 : 객체마다 다른 값을 가지기 때문
public class Object {
    ...
    public native int hashCode();
}
  • native 메서드 : OS 메서드 - C언어로 작성
    • C언어로 작성 but hashCode()를 통해 java로 작성 된 것처럼 사용
    • JNI : 다른 언어로 작성 but java로 작성 된 것처럼 사용

▶ equals() vs hashCode()

▷ 처음엔 둘 다 객체의 주소를 이용
▷ 그러나 equals()는 보통 iv를 가지고 이용하도록 오버라이딩 함
▷ equals() 오버라이딩 → hashCode() 오버라이딩
▷ 왜? equals() 결과가 true이면 → hashCode() 결과도 true!
▷ equals()는 iv 비교하고 있는데 → hashCode()는 주소 비교하고 있으면
▷ equals() == true → hashCode() == false
▷ 그래서 equals()가 오버라이딩 하면 → hashCode()도 오버라이딩!
String str1 = new String("abc");
String str2 = new String("abc");

System.out.println(str1.equals(str2));

System.out.println(str1.hashCode());
System.out.println(str2.hashCode());

// console
true
96354
96354

▶ System.identityHashCode(Object obj) = Object.hashCode()

▷ System.identityHashCode(Object obj)도 객체의 주소 반환
▷ 객체의 주소 = 서로 다름
▷ 다른 값으로 반환 = System.identityHashCode 사용!
System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2));

// console
123961122
1227229563

▶ 32bit JVM vs 64bit JVM

▷ 32bit JVM = 4byte = int
▷ 64bit JVM = 8byte = long


▶ 64bit JVM에서 hashCode() 사용하면?

▷ 64bit JVM : long에서 → hashCode() : int로 반환
▷ 8byte(long)를 → 4byte(int)로 반환
▷ 8byte를 → 반토막내서 반환
▷ 그럼 해쉬코드가 겹칠 수도 있음
  • ex1) 11112222 → 반토막 → 2222
  • ex2) 33332222 → 반토막 → 2222



Ch9 - 5. Object 클래스의 메서드 : toString()


▶ toString()이란?

▷ to String
▷ 객체를 String(문자열)으로 변환하기 위한 메서드
  • Object 클래스의 toString
    public String toString() {
      // return 설계도객체.클래스 이름 at(@) 16진수 문자열(객체 주소);
      return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    



Ch9 - 6. toString()의 오버라이딩


▶ toString()의 오버라이딩이란?

▷ toString() : 객체(iv 집합)를 문자열(String)로 변환 = iv 값을 문자열로 변환


▶ 실습

▷ 오버라이딩 하지 않고 toString() 출력
  • 클래스 이름 @위치 객체 주소
      class Card {
          String kind;
          int number;
        
          Card() {
              this("SPADE", 1);
          }
        
          Card(String kind, int number) {
              this.kind = kind;
              this.number = number;
          }
      }
        
      class Ex9_4 {
          public static void main(String[] args) {
              Card c1 = new Card();
              Card c2 = new Card();
        
              System.out.println(c1.toString());
              System.out.println(c2.toString());
          }
      }
        
      // console
      Card@2401f4c3
      Card@7637f22
    
▷ toString() 오버라이딩
  • iv인 kind와 number를 문자열로 바꾸어서 반환
      class Card {
          String kind;
          int number;
        
          Card() {
              this("SPADE", 1);
          }
        
          Card(String kind, int number) {
              this.kind = kind;
              this.number = number;
          }
            
          // Object 클래스의 toString() 오버라이딩
          public String toString() {
              return "kind : " + kind + ", number : " + number;
          }
      }
        
      class Ex9_4 {
          public static void main(String[] args) {
              Card c1 = new Card();
              Card c2 = new Card();
        
              System.out.println(c1.toString());
              System.out.println(c2.toString());
          }
      }
        
      // console
      kind : SPADE, number : 1
      kind : SPADE, number : 1
    
▷ equals() 오버라이딩
  • 객체 주소 비교 → iv 값 비교
    class Card {
        String kind;
        int number;
      
        Card() {
            this("SPADE", 1);
        }
      
        Card(String kind, int number) {
            this.kind = kind;
            this.number = number;
        }
          
        // Object 클래스의 toString() 오버라이딩
        public String toString() {
            return "kind : " + kind + ", number : " + number;
        }
          
        // Object 클래스의 equals() 오버라이딩
        public boolean equals(Object obj) {
            if(!(obj instanceof Card))
                return false;
              
            Card card = (Card)obj;
            // kind는 String, String은 equals!, == 안됨
            return this.kind.equals(card.kind) && this.number == card.number;
        }
    }
      
    class Ex9_4 {
        public static void main(String[] args) {
            Card c1 = new Card();
            Card c2 = new Card();
      
            System.out.println(c1.equals(c2));
              
            System.out.println(c1.toString());
            System.out.println(c2.toString());
        }
    }
      
    // console
    true
    kind : SPADE, number : 1
    kind : SPADE, number : 1
    
▷ hashCode() 오버라이딩
  • equals() 오버라이딩 → hashCode() 오버라이딩
  • return Objects.hash(kind, number);
    • Objects : 객체와 관련된 유용한 메서드를 제공하는 유틸 클래스
    • (kind, number) : 매개변수가 가변인자라서 여러 개 호출 가능
      class Card {
          String kind;
          int number;
          
          Card() {
              this("SPADE", 1);
          }
          
          Card(String kind, int number) {
              this.kind = kind;
              this.number = number;
          }
              
          // Object 클래스의 toString() 오버라이딩
          public String toString() {
              return "kind : " + kind + ", number : " + number;
          }
              
          // Object 클래스의 equals() 오버라이딩
          public boolean equals(Object obj) {
              if(!(obj instanceof Card))
                  return false;
                  
              Card card = (Card)obj;
              return this.kind.equals(card.kind) && this.number == card.number;
          }
              
          // Object 클래스의 hashCode() 오버라이딩
          public int hashCode() {
              return Objects.hash(kind, number);
          }
              
      }
          
      class Ex9_4 {
          public static void main(String[] args) {
              Card c1 = new Card();
              Card c2 = new Card();
          
              System.out.println("equals : " + c1.equals(c2));
                  
              System.out.println("hashCode : " + c1.hashCode());
              System.out.println("hashCode : " + c2.hashCode());
                  
              System.out.println("toString : " + c1.toString());
              System.out.println("toString : " + c2.toString());
          }
      }
          
      // console
      equals : true
      hashCode : -1842861219
      hashCode : -1842861219
      toString : kind : SPADE, number : 1
      toString : kind : SPADE, number : 1