자바 Object 클래스 | 자바 입문강좌 36

자바 Object 클래스

모든 자바 앱의 클래스는 Object 클래스로 부터 시작합니다. Object 클래스가 모든 클래스의 조상 혹은 base 라고 할 수 있습니다. 주로 운영체제와 자바가상머신의 사이의 관리를 위한 역할을 합니다.

자바 Object 클래스의 이름인 Object (객체)가 말해주는 것은 자바는 객체로 부터 시작하고 객체로 끝맺음 한다는 것 입니다. 그래서 자바는 모든 것이 객체다라고 말하는 것 입니다.

아주 디테일하게 들어가면 int, float 같은 자바의 코어 데이터 타입은 객체는 아니라고 합니다. 대신 기본 데이터 형을 클래스로 만들기 위해 Wrapper(포장지) 클래스를 별도로 사용할 수 있습니다.

일반적으로 저수준에서 데이터가 어떻게 돌아가는 것 까지는 응용 프로그램 개발자들이 들여다 볼일은 거의 없습니다. 어쨋든 모든 자바의 클래스는 Object 에서 시작한다는 사실이 중요합니다.

Object 클래스에는 몇 가지 메소드들이 있습니다.

Object 예제

몇 가지 예제를 살펴보는 것이 Object 구조를 이해하는데 도움이 됩니다.

모든 클래스는 묵시적으로 extends Object 를 합니다. 명시적으로 해도 문제가 되지 않습니다.

package com.kay;

public class Main {

    public static void main(String[] args) throws CloneNotSupportedException {
        MyObject obj1 = new MyObject(101, "First Object");
        MyObject obj2 = obj1;

        System.out.println(obj1.toString());
        System.out.println(obj2.toString());

        System.out.println(obj1.equals(obj2));

        MyObject obj3 = new MyObject(102, "Second Instance");

        System.out.println(obj3.toString());
        System.out.println("- obj1 equal to obj3? " + obj1.equals(obj3));

//        hashcode for instance address
        System.out.format("- Hash Code of obj1 : %X\n", obj1.hashCode());
        System.out.format("- Hash Code of obj2 : %X\n", obj2.hashCode());
        System.out.format("- Hash Code of obj3 : %X\n", obj3.hashCode());

//        toString Override
        Object obj4 = new OverrideToString();
        System.out.println(obj4.toString());

        System.out.println("--------------------------------");
//    Clone
        CloneEx cl1 = new CloneEx(1001, "Clone one");
        CloneEx copiedClone = (CloneEx)cl1.clone();
        System.out.println("[clone test]");
        System.out.println("-- cl1         = " + cl1);
        System.out.println("-- copiedClone = " + copiedClone);
        System.out.println("cl1.id         = " + cl1.id);
        System.out.println("copiedClone.id = " + copiedClone.id);

    }
}

class MyObject extends Object{
    int objId;
    String objName;

    public MyObject(int objId, String objName) {
        this.objId = objId;
        this.objName = objName;
    }

}

class OverrideToString{
    @Override
    public String toString() {
        return "* Overrided to String *";
    }
}

class CloneEx implements Cloneable{
    int id;
    String name;

    public CloneEx(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
com.kay.MyObject@7ef20235
com.kay.MyObject@7ef20235
true
com.kay.MyObject@27d6c5e0
- obj1 equal to obj3? false
- Hash Code of obj1 : 7EF20235
- Hash Code of obj2 : 7EF20235
- Hash Code of obj3 : 27D6C5E0
* Overrided to String *
--------------------------------
[clone test]
-- cl1         = com.kay.CloneEx@4783da3f
-- copiedClone = com.kay.CloneEx@378fd1ac
cl1.id         = 1001
copiedClone.id = 1001

extends 를 명시적으로 작성해봅니다. 없어도 컴파일러가 추가하는 내용입니다. class 키워드를 넣기만 하면 Object 의 속성을 모두 가지고 시작합니다.

class MyObject extends Object{
    int objId;
    String objName;

    public MyObject(int objId, String objName) {
        this.objId = objId;
        this.objName = objName;
    }

}

아래의 코드는 toString 을 오버라이딩합니다. 기본 toString 은 해시코드가 포함된 클래스 이름을 반환합니다.

class OverrideToString{
    @Override
    public String toString() {
        return "* Overrided to String *";
    }
}

아래의 코드는 인스턴스를 복제하는 clone 메소드의 구현입니다. 인터페이스 Cloneable 과 Exception 이 필료합니다.

class CloneEx implements Cloneable{
    int id;
    String name;

    public CloneEx(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

실행 결과는 다음과 같습니다.

com.kay.MyObject@7ef20235
com.kay.MyObject@7ef20235
true
com.kay.MyObject@27d6c5e0
- obj1 equal to obj3? false
- Hash Code of obj1 : 7EF20235
- Hash Code of obj2 : 7EF20235
- Hash Code of obj3 : 27D6C5E0
* Overrided to String *
--------------------------------
[clone test]
-- cl1         = com.kay.CloneEx@4783da3f
-- copiedClone = com.kay.CloneEx@378fd1ac
cl1.id         = 1001
copiedClone.id = 1001
class com.kay.OverrideToString

equals 메소드는 원본과 대조를 합니다. 두 객체의 값이 같지 않아도 주소가 같으면 true를 리텅합니다. 쉽게말해 참조 변수를 비교합니다.

hashCode는 메모리의 주소입니다. 자바는 해시 방식으로 메모리 주소를 저장합니다. 해시의 키를 매개변수로 값을 가져옵니다. 이 16진수 값은 힙메모리의 주소입니다. 메모리의 주소가 같다는 것은 인스턴스가 같다는 말입니다. 클래스 참조변수는 여러개가 하나의 메모리 인스턴스를 가리킬 수 있습니다.

C++에서는 포인터로 직접관리하던 메모리 주소를 자바가상머신(JVM)이 관리하기 때문에 사용자들은 더 복잡한 저수준 프로그래밍을 하지 않아도 됩니다. 약간 장점이자 단점이죠. 어차피 메모리에 대한 모델은 C언어 계열에서 제일 명확하게 설명이 됩니다. 자바의 클래스는 한층 더 껍질을 포장한 것이므로 아무리 쉬워도 때로 부족함을 느낍니다.

요약

Object 클래스는 모든 클래스의 조상인 만큼 어떻게 구성되어 있는지 한번쯤 살펴보고 갈 필요가 있습니다.

참고문서

Object (Java SE 10 & JDK 10 ) (oracle.com)

Object class in Java – GeeksforGeeks

Leave a Comment