[Java] Object의 내장 함수 기능을 알아봅니다.

엄진환·2021년 8월 5일
0


Java 16 공식 문서를 참고했습니다.

Java에서의 Object

Java에서 모든 클래스는 Object를 상속받게 됩니다.
그러면 실제로 클래스 안에서 바로 사용할 수 있는 Object 메소드의 기능 중 hashCode, toString, equals 메소트를 예제 코드와 함께 알아봅니다.

int hashCode(void)

Object의 해시 코드 값을 반환하는 함수입니다.

public class HelloWorld {
    private int num = 3;
    public static void main(String[] args) {
        HelloWorld helloWorld = new HelloWorld();
        System.out.println(helloWorld.hashCode());
        helloWorld.numChange(5);
        System.out.println(helloWorld.hashCode());
    }
    public void numChange(int a) {
        num = a;
    }
}

결과

918221580
918221580

HelloWorld 클래스의 인스턴스의 멤버 변수 수정에도 같은 해시 코드값을 가지기 때문에 객체 안의 값이 아닌 메모리 주소로 해시 코드를 만드는 것으로 유추할 수 있었습니다.

boolean equals(Object)

equals 메소드는 매개변수의 객체와 자신이 같은지 비교하는 함수입니다. 이 내용은 예제보다는 Object.java에 정의된 내용을 확인하면 바로 알 수 있습니다.

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

Object.java의 내부 코드에서 ==연산을 통해서 비교하므로 메모리 주소가 같은 객체를 비교하는 함수인 것을 알 수 있습니다.

String toString(void)

객체를 문자열로 반환합니다. 재정의하지 않으면 "패키지이름.클래스이름@해시코드"로 문자열을 반환합니다.

public class HelloWorld {
    public static void main(String[] args) {
        HelloWorld helloWorld = new HelloWorld();
        System.out.println(helloWorld.toString());
    }
}

결과

com.programmers.java.HelloWorld@36baf30c

Object clone(Object)

현재 객체를 복사해서 복사한 내용의 새로운 객체를 생성합니다.

class A implements Cloneable{
    private int num = 3;
    private B b;
    public void setNum(int n)
    {
        num = n;
    }
    public int getNum()
    {
        return num;
    }

    public void CreateB() {
        b = new B();
    }

    public void setBData(String s)
    {
        b.setStr(s);
    }

    public String getBData()
    {
        return b.getStr();
    }

    public Object CloneObject() throws CloneNotSupportedException{
        return super.clone();
    }
}

class B{
    private String str = "This is B!";
    public void setStr(String s)
    {
        str = s;
    }
    public String getStr()
    {
        return str;
    }
}


public class HelloWorld {
    public static void main(String[] args) {
        A a = new A();
        a.CreateB();
        System.out.println("초기 a 객체 값 : " + a.hashCode() + ", " + a.getNum() + ", " + a.getBData());

        try {
            A a2 = (A)a.CloneObject();
            a.setNum(11);
            a.setBData("This is origin!");
            System.out.println("a 객체 원본 : " + a.hashCode() + ", " + a.getNum() + ", " + a.getBData());
            System.out.println("a 객체 사본 : " + a2.hashCode() + ", " + a2.getNum() + ", " + a2.getBData());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

결과

초기 a 객체 값 : 1554547125, 3, This is B!
a 객체 원본 : 1554547125, 11, This is origin!
a 객체 사본 : 1418481495, 3, This is origin!

primitive 값(int, float 등)은 원본, 사본 클래스가 수정에서 독립적인 값을 가지는 것을 확인할 수 있지만 Object 같은 객체의 멤버 변수의 경우에는 같은 주소를 가리키고 있기 때문에 원본 객체의 b 멤버 변수를 수정해도 사본까지 영향을 주는 것을 확인할 수 있습니다.
깊은 복사를 위해서는 clone을 재정의해야 하는 것을 알 수 있습니다.

final Class<?> getClass(void)

현재 인스턴스의 런타임 클래스를 가져옵니다.

class A {
	...
}
class B {
	...
}


public class HelloWorld {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        System.out.println(a.getClass());
        System.out.println(b.getClass());
    }
}

결과

class com.programmers.java.A
class com.programmers.java.B

참고 문서

https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/Object.html

profile
개발 공부 블로그

0개의 댓글