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로 작성 된 것처럼 사용
- C언어로 작성 but hashCode()를 통해 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