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

eeminsu·2021년 10월 9일
0

자바의 정석을 통해 공부한 내용을 요약하였습니다.

1. Object 클래스

Object 클래스는 모든 클래스의 최고 조상 클래스이다.
Object 클래스의 멤버들은 모든 클래스에서 바로 사용 가능하다.


Object 클래스는 멤버변수 없이 11개의 메서드만을 가지고 있다.
아래는 대표적인 메서드들에 대한 내용이다.


2. eqauls(Obejct obj)

매개변수로 객체의 참조변수를 받아서 비교하여 결과를 boolean값으로 알려주는 메서드이다.

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

equals 메서드는 객체의 주소값(참조변수에 저장된 값)을 통해 비교하기 때문에
같은 클래스에서 생성된 인스턴스가 같은 멤버변수 값을 가질지라도
주소값이 다르기 때문에 false를 반환한다.

즉, 두 참조변수에 저장된 값(주소값)이 같은지를 판단하는 기능밖에 할 수 없다.
하지만 오버라이딩을 통해 주소값이 아닌 객체의 저장된 내용을 비교하도록 변경할 수 있다.
String 클래스 역시 Object의 equals 메서드를 오버라이딩하여 문자열을 비교하고 있다.



3. hashCode()

객체의 주소값으로 해시코드를 만들어 반환하는 메서드이다.
즉 객체들은 모두 다른 해시코드를 갖게 된다.

public class object{
	public native int hashCode();
}

native 메서드는 OS의 구현된 메서드를 그대로 사용하는 메서드이다.

만약 equals 메서드를 오버라이딩하여 주소값이 아닌
인스턴스 멤버의 내용을 비교하도록 변경하였다면
hashCode 메서드 또한 오버라이딩하여 변경해주어야 한다.
equals 결과가 true인 두 객체의 해시코드는 같아야 하기 때문이다.

해시코드는 int형으로 반환된다.
32bit JVM에서는 해시코드가 중복되는 경우가 없지만
64bit JVM에서는 long을 int형으로 반환하기 때문에 해시코드가 중복될 수 도 있다.



4. toString()

객체에 대한 정보를 String으로 제공할 목적으로 정의한 메서드이다.
객체에 대한 정보를 제공한다는 것은 인스턴스 변수에 저장된 값을 문자열로 표현한다는 뜻이다.

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

toString()을 오버라이딩 하지 않는 다면 위와 같은 내용이 그대로 사용된다.

toString()은 인스턴스나 클래스에 대한 정보 또는 인스턴스 변수들의 값을
문자열로 변환하여 반환하도록 오버라이딩되는 것이 일반적
이다.
String클래스의 toString()은 String인스턴스가 갖고 있는 문자열을 반환하도록 오버라이딩 되어있으며 Date클래스는 Date인스턴스가 갖고 있는 날짜와 시간을 문자열로 반환하도록 오버라이딩 되어있다.


5. clone()

자신을 복제하여 새로운 인스턴스를 생성하는 메서드이다.
Object클래스에 정의된 clone()은 단순히 인스턴스변수의 값만 복사하기 때문에
참조타입의 인스턴스 변수가 있는 클래스는 완전한 복제가 이루어지지 않는다.

clone()을 사용하기 위해선 복제할 클래스가 Cloneable 인터페이스를 구현해야 하며
clone()을 오버라이딩 하면서 접근 제어자를 public으로 변경해주어야 한다.
그래야지만 상속관계가 없는 다른 클래스에서 clone()을 호출할 수 있다.

public class Object{
	protected native Object clone() throws CloneNotSupportedException;
}

Cloneable을 구현하지 않은 클래스 내에서 호출될 시 예외를 발생시킨다.

class Point implements Cloneable { //Cloneable 인터페이스 구현
	public Object clone(){ 		// 접근제어자 public으로 변경
    	Object obj = null;
        try{
        	obj = super.clone(); // try-catch내에서 조상클래스의 clone() 호출
        }
        catch (CloneNotSupportedException e) {}
        return obj;
    }
}

Cloneable인터페이스를 구현한 클래스의 인스턴스만 clone()을 통한 복제가 가능한 이유는
인스턴스의 데이터를 보호하기 위함이다.

5-1. 얕은 복사와 깊은 복사

clone()은 단순히 객체에 저장된 값을 그대로 복제하기 때문에
객체가 참조하고 있는 객체까지 복제하지 않는다.
이러한 복제를 얕은 복사라고 한다.
반면에 원본이 참조하고 있는 객체까지 복제하는 것깊은 복사라고 한다.

얕은 복사를 하게 되면 복제본의 참조 객체가 원본의 참조 객체인스턴스를 가리키게 된다.

아래 코드는 얕은 복사의 코드 예시다.

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

깊은 복사를 하기위해선 위 코드에서 아래와 같이 복제된 객체가
새로운 인스턴스를 참조하게 해주면 된다.

Circle c = (Circle)obj;
c.p = new Point(this.p.x, this.p.y);
profile
안되면 될 때까지

0개의 댓글