SHUSTORY

11-1 Object 클래스 본문

프로그래밍/JAVA

11-1 Object 클래스

어서오시우 2023. 3. 6. 18:11
728x90

java.lang 패키지

자바로 프로그램을 구현하면서 사용한 String, Integer와 같은 클래스는 java.lang 패키지에 속해 있다.

String 클래스의 전체 이름은 java.lang.String이고, Integer 클래스의 전체 이름은 java.lang.Integer이다.

이와 같이 java.lang 패키지에는 기본적으로 많이 사용하는 클래스들이 포함되어 있다.

 

자바 프로그래밍에서 외부 패키지에 선언한 클래스를 사용할 때는 import문으로 클래스가 어느 패키지에 속해 있는지

선언해야 하는데, String 클래스를 쓰면서 import.java.lang.String.*; 문장을 작성하지 않아도 되는 이유는 무엇일까?

java.lang 패키지는 컴파일할 때 import.java.lang.*; 문장이 자동으로 추가되기 때문이다.

즉 프로그래머가 import 문장을 직접 쓰지 않아도 java.lang 패키지의 모든 하위 클래스를 참조할 수 있다.

 

 

모든 클래스의 최상위 클래스 Object

Object 클래스는 모든 자바 클래스의 최상위 클래스이다.

즉 모든 클래스는 Object의 상속을 받는다는 것이다.

그런데 클래스를 선언할 때 extends Object를 작성하지 않는 이유는 무엇일까?

위에서 말했던 것과 같은 개념으로 컴파일 과정에서 자동으로 extends Object가 쓰이기 때문이다.

 

우리가 직접 만드는 클래스뿐 아니라 JDK에서 제공하는 클래스도 모두 Object 클래스의 상속을 받는다.

주로 사용되는 Object 메서드는 다음과 같다.

메서드 설명
String toString( ) 객체를 문자열로 표현하여 반환한다.
재정의하여 객체에 대한 설명이나 특정 멤버 변수 값을 반환한다.
boolean equals(Object obj) 두 인스턴스가 동일한지 여부를 반환한다.
재정의하여 논리적으로 동일한 인스턴스임을 정의할 수 있다.
int hashCode( ) 객체의 해시 코드 값을 반환한다.
Object clone( ) 객체를 복제하여 동일한 멤버 변수 값을 가진 새로운 인스턴스를 생성한다.
class getClass( ) 객체의 Class 클래스를 반환한다.
void finalize( ) 인스턴스가 힙 메모리에서 제거될 때까지 가비지 컬렉터에 의해 호출되는 메서드이다.
네트워크 연결 해제, 열려 있는 파일 스트림 해제 등을 구현한다.
void wait( ) 멀티스레드 프로그램에서 사용하는 메서드이다.
스레드를 '기다리는 상태'로 만든다.
void notify( ) wait( ) 메서드에 의해 기다리고 있는 스레드를 실행 가능한 상태로 가져온다.

Object 메서드 중에는 재정의할 수 있는 메서드도 있고, 그렇지 않은 메서드도 있다.

* 자바 가상 머신과 관련된 메서드는 재정의할 수 없다.

 

 

toString( ) 메서드

Object 클래스에서 기본으로 제공하는 toString( ) 메서드는 이름처럼 객체 정보를 문자열(String)으로 바꿔준다.

Object 클래스를 상속받은 모든 클래스는 toString( )을 재정의할 수 있다.

String이나 Integer 등 여러 JDK 클래스에는 toString( ) 메서드가 이미 재정의되어 있다.

 

Object 클래스의 toString( )메서드

toString( ) 메서드는 인스턴스 정보를 문자열로 반환하는 메서드로, 원형은 생성된 인스턴스의 이름과 주소 값을 보여준다.

 

예제01

 

17행에서 출력문에 참조 변수를 넣으면 인스턴스 정보가 출력되는데, 이 때 자동으로 호출되는 메서드가 toString( )이다.

여기에서 호출되는 toString( )은 Object 클래스의 메서드이며, 메서드의 원형은 다음과 같다.

toString( ) 메서드 원형

 

String과 Integer 클래스의 toString( ) 메서드

toString( ) 메서드가 호출된 경우라도 출력결과가 '클래스 이름@해시 코드 값'이 아닌 경우가 있는데,

이는 해당 메서드가 재정의되었기 때문이다.

JDK에서 제공하는 클래스 중에는 toString( ) 메서드를 미리 재정의한 클래스가 많다.

메서드가 재정의된 클래스에서는 메서드의 원형이 아닌 재정의된 메서드가 호출되는 것이다.

String/Integer 클래스_재정의된 toString( ) 메서드
위 메서드 출력값

toString( ) 메서드를 직접 재정의할 수도 있다.

만약 메서드 정의를 기억하고 있다면 선언부를 직접 적을 수도 있고,

혹은 소스 코드 내부에서 마우스 우클릭 후 오버라이드 기능을 통해 자동으로 메서드 재정의 코드를 넣을 수도 있다.

 

Override

 

예제02

 

위와 같이 toString( ) 메서드를 재정의하면 객체의 참조 변수를 이용해 원하는 문자열을 표현할 수 있다.

 

 

equals( ) 메서드

equals( ) 메서드의 원래 기능은 두 인스턴스의 주소 값을 비교하여 boolean 값을 반환하는 것이다.

주소 값이 같다면 당연히 같은 인스턴스이며, 이를 물리적 동일성이라고 한다.

그런데 서로 다른 주소 값을 가지더라도 논리적 동일성을 구현할 때에도 equals( ) 메서드를 재정의하여 사용할 수 있다.

 

Object 클래스의 equals( ) 메서드

인스턴스를 가리키는 참조 변수가 두 개 있을 때 이 인스턴스가 물리적으로 같다는 것은,

두 인스턴스의 주소 값이 같은 경우를 말한다. 즉 동일한 메모리 주소를 가리키고 있다는 것이다.

이 경우 equals( ) 메서드를 이용해 두 변수를 비교하면 true값이 반환된다.

 

예제03_Object 클래스의 equals( ) 메서드 사용하기

 

그렇다면 서로 다른 주소를 가지고 있지만 동일한 정보를 지닌 값이 있고,

equals( ) 메서드를 통해 이를 같은 인스턴스라고 반환하고 싶다면 다음 예제04와 같이 재정의할 수 있다.

예제04_EqualsTestEx class

 

EqaulsTestEx 전체코드

 

예제04_출력값

 

서로 다른 메모리 주소에 존재하는 인스턴스이더라도 학번이 같은 학생을 동일하다고 출력하도록

equals( ) 메서드를 재정의하였다.

 

 

hashCode( ) 메서드

해시(hash)는 정보를 저장하거나 검색할 때 사용하는 자료 구조이다.

정보를 어디에 저장할 것인지, 어디서 가져올 것인지 해시 함수를 사용하여 구현한다.

해시 함수는 객체의 특정 정보( 키 값 )를 매개변수로 넣으면 그 객체가 저장되어야 할 위치나 저장된

해시 테이블 주소( 위치 )를 반환하므로 객체 정보를 알면 해당 객체의 위치를 빠르게 검색할 수 있다.

자바에서는 인스턴스를 힙 메모리에 생성하여 관리할 때 해시 알고리즘을 사용한다.

 

Object 클래스의 toString( ) 메서드 원형을 다시 살펴보면 getClass( ).getName( ) + '@' + Integer.toHexString(hashCode( ))이다. 우리가 참조 변수를 출력할 때 본 16진수 숫자 값이 '해시 코드 값'이고, 이 값은 JVM이 힙 메모리에 저장한 '인스턴스의 주소 값'이다.

즉 자바에서는 두 인스턴스가 같다면 hashCode( ) 메서드에서 반환하는 해시 코드 값이 같아야 한다.

따라서 논리적으로 같은 두 객체도 같은 해시 코드 값을 반환하도록 hashCode( ) 메서드를 재정의해야 한다.

 

 

String과 Integer 클래스의 hashCode( ) 메서드

String과 Integer 클래스의 equals( ) 메서드가 재정의되었듯 hashCode( ) 메서드도 재정의되어 있다.

또한 프로그래머가 직접 hashCode( ) 메서드를 재정의할 수도 있다.

hashCode( ) 메서드를 재정의했을 때 실제 인스턴스의 주소 값은 System.indentityHashCode( ) 메서드를 사용하여

출력할 수 있다.

 

 

clone( ) 메서드

객체 원본을 유지해 놓고 복사본을 사용하거나, 기본 틀의 복사본을 사용해 동일한 인스턴스를 만들어

복잡한 생성 과정을 간단히 하고자 할 때 clone( ) 메서드를 사용할 수 있다.

clone( ) 메서드는 Object에 다음과 같이 선언되어 있으며, 객체를 복제해 또 다른 객체를 반환해 주는 메서드이다.

clone( ) 메서드

clone( ) 메서드를 사용하려면 객체를 복제해도 된다는 의미로 클래스에 Cloneable 인터페이스를 구현해야 한다.

만약 clone( ) 메서드만 재정의하고 인터페이스 미선언 시 메서드 호출 시 CloneNotSupportedException이 발생한다.

* Cloneable 인터페이스를 선언해도 별도로 구현해야하는 메서드는 없다.

  이렇게 구현할 메서드가 없는 인터페이스를 마커 인터페이스라고 한다.

 

예제05_clone( ) 메서드 예제

'프로그래밍 > JAVA' 카테고리의 다른 글

11-3 Wrapper 클래스  (0) 2023.03.06
11-2 String 클래스  (0) 2023.03.06
10-3 인터페이스 요소 살펴보기  (0) 2023.03.05
10-2 인터페이스와 다형성  (0) 2023.03.05
10-1 인터페이스  (0) 2023.03.05