ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] Object Class 1편 equals hashCode toString clone 메서드
    JAVA 2022. 8. 4. 12:02
    728x90
    반응형

    1. Object Class

    Object는 모든 클래스의 최고 조상으로 11개의 메서드를 가지고 있습니다.

    1. protected Object clone( ) : 객체 자신의 복사본을 반환한다.
      • 오버 라이딩을 통해 접근제어자를 public으로 바꿔줘야 한다.
    2. public boolean equals(Object obj) : 객체 자신과 객체 obj가 같은 객체인지 알려준다.
      • 참조 변수에 저장된 주소를 비교한다.
      • 오버 라이딩을 통해 주소가 아닌 멤버 비교도 할 수 있다.
      • equals 메서드를 오버 라이딩하면 hashCode 메서드도 오버 라이딩해줘야 한다.
        • (중요) equals 메서드의 결과가 true이면 두 객체의 해시 코드는 같아야 하기 때문입니다.
    3. protected void finalize( ) : (거의 사용되지 않음) 객체 소멸 시 가비지 컬렉터에 의해 자동 호출된다.
    4. public Class getClass( ) : 객체 자신의 클래스 정보(설계도 정보)를 담고 있는 class 인스턴스를 반환한다.
      • class명 앞글자가 대문자이면 클래스 정보를 담기 위한 클래스이다.
      • getClass를 통해 얻는 것으로 객체 생성 및 객체 정보에 대해 알 수 있다.
        • 소스파일을 컴파일하면 *. class 파일이 생성된다.
        • *. class 파일을 실행하면 해당 파일명의 객체가 생성되는데 이게 설계도이다.
    5. public int hashCode( ) : 객체 자신의 해시 코드를 반환한다.
      • 객체의 해시 코드(정수 값)를 반환하는 메서드이다.
      • Object 클래스의 hashCode 메서드는 객체의 주소를 int로 변환해서 반환한다.
      • equals 메서드를 오버 라이딩하면 hashCode 메서드도 오버 라이딩해줘야 한다.
        • (중요) equals 메서드의 결과가 true이면 두 객체의 해시 코드는 같아야 하기 때문이다.
        • public int hashCode( ){return Object.hash(가변 인자);}
          • 가변 인자에는 매개변수를 1개만 넣어도 되고 100개를 넣어도 상관없습니다.
    6. public String toString( ) : 객체 자신의 정보를 문자열로 반환한다.
      1. 객체를 문자열(String)로 변환하기 위한 메서드
      2. 객체를 toString 메서드를 사용해서 출력하면 "클래스 이름 + @ + 주소 값을 int형으로 변환한 값"이 나온다.
    7. public void notify( ) : 객체 자신을 사용하려고 기다리는 스레드를 하나만 깨운다.
    8. public void notifyAll( ) : 객체 자신을 사용하려고 기다리는 모든 스레드를 깨운다.
    9. public void wait( )
    10. public void wait(long timeout)
    11. public void wait(long timeout, int nanos)
      • 9~11번 메서드의 대한 설명
        • 다른 스레드가 notify( )나 notifyAll( )을 호출할 때까지 현재 스레드를 무한히 또는 지정한 시간(timeout은 천분의 1초, nanos는 10^9분의 1초) 동안 기다리게 한다.

    1-1. public boolean equals(Object obj)

    • Object클래스에 정의된 equals 메서드는 참조 변수 값(객체의 주소)을 비교한다.
    • equals 메서드를 오버 라이딩해서 인스턴스 변수의 값을 비교하도록 바꿀 수 있습니다.
    class Person {
        long id;
        
        public boolean equals(Object obj){ // equals 오버라이딩
            if(obj != null && obj instanceof Person){
                return id == ((Person)obj).id;
            }else{
                return false;
            }
        }
        Person(long x){
            id = x;
        }
    }
    
    class Person2 {
        long id;
    
        Person2(long x){
            id = x;
        }
    }
    
    Person p1 = new Person(100L);
    Person p2 = new Person(100L);
    // 오버라이딩을 통해 인스턴스 변수를 비교하게 바꾸었기 때문에 true가 반환된다.
    System.out.println(p1.equals(p2)); // true
    // == 연산자는 주소값을 비교한다.
    // 서로 다른 객체를 만들었기 때문에 주소값이 같을 수 없다.
    System.out.println(p1 == p2); // false
            
    Person2 p3 = new Person2(100L);
    Person2 p4 = new Person2(100L);
    // 오버라이딩 없이 euqals 메서드를 사용하면 주소값을 비교한다.
    System.out.println(p3.equals(p4)); // fasle

     

    1-2. public int hashCode( )

    • 객체의 해시 코드(int타입의 정수)를 반환하는 메서드
      • 다량의 데이터를 저장 및 검색하는 해싱 기법에 사용된다.
    • Object클래스의 hashCode( )는 객체의 내부 주소를 정수로 변환해서 반환한다.
    • equals 메서드를 오버 라이딩하면 hashCode 메서드도 같이 오버 라이딩해야 한다.
      • equals 메서드의 결과가 true인 두 객체의 hashCode는 같아야 하기 때문이다.
    • System.identityHashCode(Object obj)는 내부 주소를 정수로 변환해서 반환한다.
      • 오버 라이딩 불가
    // ⭐equals와 hashCode를 오버라이딩 O
    T t1 = new T(1);    
    T t2 = new T(1);
    System.out.println(t1.equals(t2)); // true
    System.out.println(t1.hashCode()); // 32
    System.out.println(t2.hashCode()); // 32
            
    // ⭐equals와 hashCode를 오버라이딩 X
    TT t3 = new TT(1);
    TT t4 = new TT(1);
    System.out.println(t3.equals(t4)); // false
    System.out.println(t3.hashCode()); // 358699161
    System.out.println(t4.hashCode()); // 517938326
            
    // ⭐String 클래스는 아직 안배웠지만 다르다.
    String str1 = new String("abc");
    String str2 = new String("abc");
    System.out.println(str1.equals(str2)); // true
    System.out.println(str1.hashCode()); // 96354
    System.out.println(str2.hashCode()); // 96354
    
    class T{
        int id;
        
        public boolean equals(Object obj){ // equals 오버라이딩
            if(obj instanceof T){
                return id == ((T)obj).id;
            }else {
                return false;
            }
        }
        
        public int hashCode(){ // hashCode 오버라이딩
            return Objects.hash(id);
        }
        
        T(int x){
            id = x;
        }
    }
    
    class TT{
        int id;
        TT(int x){
            id = x;
        }
    }

    Objects 클래스는 객체와 관련된 유용한 메서드를 제공하는 유틸 클래스이다.

    • String 클래스는 자체적으로 equals는 주소 값이 아닌 내용을 비교하게끔 오버 라이딩되어있다.
    • String 클래스는 자체적으로 hashCode를 주소 값이 아닌 내용을 정수형으로 변환해서 반환하게 오버 라이딩되어있다.

    1-3. toString( )

    • 객체의 정보를 문자열로 제공할 목적으로 정의된 메서드
    public String toString(){
        return getclass().getName() + "@" + Integer.toHexString(hashCode());
    }
    • 오버 라이딩을 통해 얼마든지 내용을 바꿀 수 있다.
    Card c1 = new Card();
    Card c2 = new Card();
    System.out.println(c1.toString()); // Card@1b701da1
    System.out.println(c2.toString()); // Card@1edf1c96
            
    Card2 c3 = new Card2();
    Card2 c4 = new Card2();
    System.out.println(c3.toString()); // kind = Diamonds, number1
    System.out.println(c4.toString()); // kind = Diamonds, number1
    
    // 일반
    class Card{
        String kind;
        int number;
        
        Card(){
            this("SPADE", 1);
        }
        Card(String kind, int number){
            this.kind = kind;
            this.number = number;
        }
    }
    // 오버라이딩
    class Card2{
        String kind;
        int number;
        
        public String toString(){ // toString() 오버라이딩
            return "kind = " + kind + ", number" + number;
        }
        
        Card2(){
            this("Diamonds", 1);
        }
        Card2(String kind, int number){
            this.kind = kind;
            this.number = number;
        }
    }

    1-4. protected Object clone( )

    • 객체 자신을 복제해서 새로운 객체를 생성하는 메서드
    • Cloneable 인터페이스를 구현한 클래스의 인스턴스만 복제할 수 있다.
    • Object 클래스에 정의된 clone 메서드는 인스턴스 변수의 값만을 복제한다.
    • 인스턴스 변수가 참 조형일 때, 참조하는 객체도 복제되게 오버 라이딩해야 한다.
    // Cloneable인터페이스를 구현한 클래스만 clone()을 호출할 수 있다.
    // 구현하지 않고 clone()을 호출하면 예외가 발생한다.
    class point implements Cloneable{
        int x;
        int y;
        point(int x, int y){
            this.x = x;
            this.y = y;
        }
        public String toString(){
            return "x = " + x + ", y = " + y;
        }
        public Object clone(){
            Object obj = null;
            try{
                obj = super.clone(); // clone메서드에는 CloneNotSupportedException이 선언되어 있기떄문에 예외처리를 해줘야한다.
            }catch(CloneNotSupportedException e){}
            return obj;
        }
    }
    
    point original = new point(1,2);
    point copy = null;
    // clone()의 리턴값이 Object 타입이기 때문에 형변화을 해줘야한다.
    // 자식타입 = 부모타입 다형성이 성립되지 않기 때문이다.
    copy = (point)original.clone();
    
    // 인스턴스 변수와 메서드까지 복사해온다.
    System.out.println(copy.x); // 1
    System.out.println(copy.y); // 2
    System.out.println(copy.toString()); // x = 1, y = 2
            
    // copy객체와 original객체는 서로 다른 객체이다.
    System.out.println(copy.hashCode()); // 1627800613
    System.out.println(original.hashCode()); // 2065530879
    728x90
    반응형
Designed by Tistory.