공부/Java

[Java-09] java.lang패키지 - Object클래스

줭♪(´▽`) 2021. 3. 5. 14:41

1. java.lang패키지

- 자바프로그래밍에 가장 기본이 되는 클래스들 포함

- import문 없이도 사용 가능

- Object, String, System 등

 

2. Object클래스

1) Object클래스의 정의와 메서드

- 모든 클래스의 조상이 되는 클래스

- Object클래스의 멤버들은 모든 클래스에서 바로 사용 가능

 

Object클래스의 메서드 설   명
protected Object clone() 객체 자신의 복사본을 반환
public boolean equals(Object obj) 객체 자신과 같은 객체 obj가 같은 객체인지 알려줌
protected void finalize() 객체가 소멸될 때 가비지 컬렉터에 의해 자동 호출
수행되어야하는 코드가 있을 때 오버라이딩함 (거의 안함)
public Class getClass() 객체 자신의 클래스 정보를 담고 있는 Class인스턴스 반환
public int hashCode() 객체 자신의 해시코드 반환
public String toString() 객체 자신의 정보를 문자열로 반환
public void notify() 객체 자신을 사용하려고 기다리는 쓰레드를 하나만 깨움
public void notifyAll() 객체 자신을 사용하려고 기다리는 모든 쓰레드를 깨움
public void wait()
public void wait(long timeout)
public void wait(long timeout, int nanos)
다른 쓰레드가 notify()나 notifyAll()을 호출할 때까지 현재 쓰레드를 무한히 또는 지정된 시간(timeout, nanos)동안 기다리게 함
(timeout은 천 분의 1초, nanos는 109분의 1초)

 

 

2) equals(Object obj)

- 매개변수로 객체의 참조변수를 받아서 비교하여 그 결과를 boolean값으로 반환

- 두 참조변수에 저장된 값(주소값)이 같은지를 판단

- 주소값이 같으면 true, 다르면 false를 반환

- 주소값이 아닌 value값을 비교하고 싶으면 equals 메서드를 오버라이딩하여 객체의 내용을 비교하면 됨

 

public boolean equals(Object obj) {
     return (this == obj);
}

 

3) hashCode()

- 해싱(hashing)기법에 사용되는 '해시함수(hash function)'를 구현한 것

- 해시함수는 찾고자하는 값을 입력하면, 그 값이 저장된 위치를 알려주는 해시코드(hash code)를 반환

- 64 bit JVM에서는 8 byte 주소값으로 해시코드(4 byte)를 만들기 때문에 해시코드가 중복될 수 있음

- String 클래스 : 문자열의 내용이 같으면 동일한 해시코드를 반환

- System.identifyHashCode(Object x) : hashCode메서드처럼 객체의 주소값으로 해시코드를 생성하기 때문에 모든 객체에 대해 항상 다른 해시코드값을 반환 (실행할 때마다 달라질 수 있음)

 

4) toString()

- 인스턴스에 대한 정보를 문자열(String)로 제공

- 클래스이름@해시코드(16진수)

 

public String toString() {
     return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

 

- toString()은 일반적으로 인스턴스나 클래스에 대한 정보 또는 인스턴스 변수들의 값을 문자열로 변환하여 반환하도록 오버라이딩하는 것이 보통임

ex) String클래스 : String인스턴스가 갖고 있는 문자열을 반환

     Date클래스 : Date인스턴스가 갖고 있는 날짜와 시간을 문자열로 변환하여 반환

 

class Card {
    String name;
    int n;
    
    Card() {
    	name = "SPADE"
        n = 10;
    }
    
    Card(String name, int n) {
    	this.name = name;
        this.n = n;
    }
    
    public String toString() {		// toString()을 오버라이딩
    	return "name: " + name + ",n: " + n;
    }
}
    

 

5) clone()

- 자신을 복제하여 새로운 인스턴스를 생성

- 원래의 인스턴스는 보전하고 새로운 인스턴스를 생성하여 사용할 때 활용

- 단순히 인스턴스변수의 값만 복사 O

  참조타입의 인스턴스 변수가 있는 클래스는 완전한 인스턴스 복제 X

  ex) 배열

  -> clone메서드를 적절하게 오버라이딩해야 함

- 복제할 클래스가 Cloneable 인터페이스를 구현해야 함

- clone()은 반드시 예외처리를 해줘야 함

class Point implements Cloneable {
    ...
    public Object clone() {
        Object obj = null;
        try {
        	obj = super.clone();
        } catch(CloneNotSupportedException e) { }
        
        return obj;
}

 

6) 공변 반환타입(covariant return type)

- JDK1.5부터 추가된 기능

- 오버라이딩할 때 조상 메서드의 반환타입을 자손 클래스의 타입으로 변경을 허용하는 것

public Point clone() {
    Object obj = null;
    try {
    	obj = super.clone();
    } catch(CloneNotSupportedException e) { }
    return (Point)obj;
}

 

7) 얕은 복사와 깊은 복사

① 얕은 복사(shallow copy)

- 단순히 객체에 저장된 값을 그대로 복제하는 것

- 객체가 참조하고 있는 객체까지 복제하지는 않음

- 원본을 변경하면 복사본도 영향을 받음

 

② 깊은 복사(deep copy)

- 원본이 참조하고 있는 객체까지 복제하는 것

- 원본을 변경해도 복사본은 영향을 받지 않음

 

 

8) getClass()

- 자신이 속한 클래스의 Class객체를 반환

- Class객체 : 이름이 'Class'인 클래스의 객체

- Class객체는 클래스의 모든 정보를 담고 있으며 클래스 당 1개만 존재

- Class객체는 클래스 파일이 클래스 로더(ClassLoader)에 의해서 메모리에 올라갈 때, 자동으로 생성

 

클래스 로더(ClassLoader)

- 실행 시에 필요한 클래스를 동적으로 메모리에 로드하는 역할

1. 기존에 생성된 클래스 객체가 메모리에 존재하는지 확인
2-1. 있으면 객체의 참조를 반환
2-2. 없으면 클래스 패스(classpath)에 지정된 경로를 따라서 클래스 파일을 찾음
2-2-1. 찾으면 해당 클래스 파일을 읽어 Class객체로 변환
2-2-2. 못찾으면 ClassNotFoundException 발생

 

- Class객체를 얻는 방법

Class cObj = new Card().getClass();	// 생성된 객체로부터 얻는 방법
Class cObj = Card.class;			// 클래스 리터럴(*.class)로부터 얻는 방법
Class cObj = Class.forName("Card");	// 클래스 이름으로부터 얻는 방법

 

- Class객체를 통해서 객체를 생성하고 메서드를 호출하는 등 보다 동적인 코드를 작성할 수 있음

Card c = new Card();
Card c = Card.class.newInstance();

 

 

 

 

 

 

참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)