도서/자바의 신

[도서/자바의 신] #12 모든 클래스의 부모 클래스는 Object에요

yulee_to 2022. 12. 23. 16:22

자바의 신

✔️이 글은 [자바의 신 - 이상민 지음] 도서를 바탕으로 정리한 글입니다. 


모든 자바 클래스의 부모인 java.lang.Object 클래스

자바에서 아무런 상속을 받지 않으면 java.lang.Object 클래스(이하 Object 클래스)를 확장한다. 

상속을 받아도 부모 클래스로 계속 올라가보면 결국엔 Object 클래스가 최상위 부모 클래스임을 알 수 있다.

그렇기 때문에 모든 클래스에서 Object 클래스에 정의된 기본적인 메소드들을 사용할 수 있다.

 

터미널에서 javap라는 명령어를 통해 하나 이상의 class의 package, protected, public 변수와 메소드에 대한 정보를 출력해준다. 명령어 뒤에는 여러 옵션들이 올 수 있고 출력할 정보를 바꿔준다.

Object 클래스에서 제공하는 메소드들의 종류는?

객체 처리를 위한 메소드

메소드 설명
protected Object clone() 객체의 복사본을 만들어 리턴한다.
public boolean equals(Object obj)  현재 객체와 매개변수로 넘겨 받은 객체가 같은지 확인, 같으면 true 다르면 false
protected void finalize() 현재 객체가 더 이상 쓸모가 없어졌을 때 가비지 컬렉터에 의해 이 메소드가 호출됨.
public Class<?> getClass() 현재 객체의 Class 클래스의 객체를 리턴한다.
public int hashCode()  객체에 대한 해시 코드(hash code) 값을 리턴, 해시 코드라는 것은 16진수로 제공되는 객체의 메모리 주소를 말함
public String toString() 객체를 문자열로 표현하는 값을 리턴

쓰레드 처리를 위한 메소드

메소드 설명
public void notify() 이 객체의 모니터에 대기하고 있는 단일 쓰레드를 깨움
public void notifyAll() 이 객체의 모니터에 대기하고 있는 모든 쓰레드를 깨움
public void wait() 다른 쓰레드가 현재 객체에 대한 notify() 메소드나 notifyAll() 메소드를 호출할 때까지 현재 쓰레드가 대기하고 있도록 함
public void wait(long timeout) wait() 메소드와 동일한 기능을 제공하며, 매개 변수에 지정한 시간만큼만 대기. 매개 변수 시간을 넘어서면 현재 쓰레드가 다시 깨어남. 시간의단위는 밀리초
public void wait(long timeout, int nanos)  wait() 메소드와 동일한 기능을 제공하지만 wait(timeout)에서 밀리초라면 이 메소드는 보다 자세한 밀리초 + 나노초(1/1000000000초) 만큼만 대기. 나노초는 0~999999사이의 값만 지정 가능

Object 클래스에서 가장 많이 쓰이는 toString() 메소드

객체를 처리하기 위한 메소드들 중에서도 toString(), equals(), hashCode(), getClass(), clone(), finalize() 메소드는 꼭 기억하고 있어야 한다.

toString()은 그 중에서도 가장 많이 사용되고, 객체의 상태를 나타내는 메소드이다.

 

이 메소드가 자동으로 호출되는 경우

  • System.out.println() 메소드에 매개 변수로 들어가는 경우
  • 객체에 대해 더하기 연산을 하는 경우, String을 제외한 참조 자료형에서 +연산을 하면 자동으로 toString이 호출되어 객체의 위치에 String값이 놓임

실제 Object 클래스에 구현된 toString 메소드

getClass().getName() + '@' + Integer.toHexString(hashCode())

getClass() 결과에 getName() 메소드를 부른 값과 앞 뒤를 구분해주는 구분자 역할을 하는 @, 마지막엔 객체의 해시 코드 값을 출력한다.

 

DTO를 사용할 때 toString() 메소드를 오버라이딩해서 내용 값들을 확인한다.

개발 툴에서 자동으로 toString()을 overriding해주는 기능이 있다.

객체는 ==만으로 같은지 확인이 안되므로, equals()를 사용하죠

==은 hashcode() 결과값을 비교하는 것이고, equals()는 객체의 내부 값을 비교한다.

equals()로 객체 값들이 같은지 확인하려면 Overriding을 해줘야 한다.

개발 툴에서 자동으로 equals()를 overriding해주는 기능이 있다.

equals() 메소드를 Overriding할 때에는 hashCode() 메소드도 같이 Overriding해줘야 equals()의 결과가 true일 때 hashCode() 결과도 같아진다. 

 

equals() Overriding 조건

  • 재귀 (reflexive) : null이 아닌 x라는 객체의 x.equals(x) 결과는 항상 true여야 함
  • 대칭 (symmetric) : null이 아닌 x와 y객체가 있을 때 y.equals(x)가 true를 리턴했다면, x.equals(y)도 반드시 true를 리턴해야만 함
  • 타동적 (transitive) : null이 아닌 x,y,z가 있을 때 x.equals(y)가 true를 리턴하고, y.equals(z)가 true를 리턴하면 x.equals(z)는 항상 true여야 함
  • 일관 (consistent) : null이 아닌 x,y가 있을 때 객체가 변경되지 않은 상황에서는 몇 번을 호출하더라도, x.eqauls(y)의 결과는 항상 true이거나 false여야 함
  • null과의 비교 : null이 아닌 x라는 객체의 x.equals(null) 결과는 항상 false여야 함

객체의 고유값을 나타내는 hashcode()

hashCode()는 객체의 메모리 주소를 16진수로 리턴해준다. 어떤 두 객체가 서로 동일하면 이 hashCode() 값도 무조건 동일해야 한다.

 

hashCode() Overriding 조건

  • 자바 애플리케이션이 수행되는 동안에 어떤 객체에 대해서 이 메소드가 호출될 때에는 항상 동일한 int 값을 리턴, 자바 실행할 때마다 같은 값일 필욘 없음
  • 어떤 두 개의 객체에 대해 equals() 결과가 true인 경우에 두 객체의 hashCode() 결과도 같아야 함
  • 두 객체의 equals() 결과가 false이라고 해서 hashCode() 결과가 무조건 달라야 할 필요 없음, 이 경우 다른 hashCode() 결과값을 사용하면 hashtable의 성능을 향상시키는 데 도움이 됨

이런 제약들로 인해 직접 Overriding하기보다는 개발툴에서 자동으로 Overriding해주는 기능을 사용하는 걸 권장한다.


정리해 봅시다

1. 모든 클래스의 최상위 부모 클래스인 Object 클래스는 어떤 패키지에 선언되어 있나요?

java.lang

2. 모든 클래스가 어떻게 선언되어 있는지 확인할 수 있는 명령어(실행 파일)의 이름은 무엇인가요?

javap

3. Object 클래스에 선언되어 있는 모든 메소드는 여러분들이 Overriding해야 하나요?

NO

4. Object 클래스의 clone() 메소드의 용도는 무엇인가요?

객체의 복사본을 만들어 return

5. System.out.println() 메소드를 사용하여 클래스를 출력했을 때 호출되는 Object 클래스에 있는 메소드는 무엇인가요?

참조 자료형을 System.out.println() 메소드에서 출력하면 toString() 메소드가 호출된 결과가 제공됨

6. 객체의 주소를 비교하는 것이 아닌, 값을 비교하려면 Object 클래스에 선언되어 있는 어떤 메소드를 overriding해야 하나요?

equals()

7. Object 클래스에 선언되어 있는 hashCode()라는 메소드는 어떤 타입의 값을 리턴하나요?

int

 

728x90