• [Java] :: Object Class

    2018. 2. 26. 18:29

    by. 위지원





    JDK 라이브러리에 lang 패키지 안에는 Object 라는 클래스를 가지고 있습니다. 이 클래스는 다른 클래스의 Super Class로 존재합니다.

    JAVA API 페이지 ( https://docs.oracle.com/javase/8/docs/api/overview-tree.html ) 를 가면 Object Class를 제외한 모든 Class가 Object Class를 상속 받고 있는 것을 확인할 수 있습니다.


    그래서 GoodsInfo,Account처럼 우리가 작성한 클래스든 String,InputStream과 같은 JDK lib Class든 Object를 상속받고있으며 그 하위 클래스도 결국은 Object를 최상단의 Super Class로 가지게 됩니다.





    Object API 사이트내에 작성된 내용을 보면 Object는 여러개의 Method들을 가지고있으며 이 Method를 다른 Class에서 사용하기 위하여 Object를 상속받는 것입니다.






    1. toString : 객체가 가지고 있는 값을 문자열로 만들어 return 합니다.


    사용 예시는 아래와같습니다.



    우리가 직접만든 클래스에도 적용할 수 있습니다.


    하지만 이 결과는 Object class의 toString의 결과로 우리가 원하는 값과는 조금 거리가 있기때문에 toString class를 오버라이드해서 사용해봅시다.


    아니 그러면 어차피 오버라이드해서 사용할 것이라면 굳이 Object Class를 상속받을 이유가 있을까요? 그 이뉴는 우리가 모르는 곳에서 자동으로 호출 되기때문입니다. 방금 작성한 코드 아래와 같이 수정한 뒤 출력하면 동일한 결과가 출력됩니다.






    2. equals 메서드 : 객체가 가지고 있는 값을 비교 합니다


    사용 예시는 다음과 같습니다. 그런데 아래에 조금 눈여겨 볼것이 있습니다. 둘다 같은 값을 가지는 객체를 생성을 했는데 그 결과 값이 다릅니다.

    equals는 참조 값으로 비교를 하기때문에 이런 결과가 출력 되는 것입니다.




    그래서 아까 toString할때와 마찬가지로 equals가 의미 있는 결과를 리턴하게 하기 위하여 오버라이딩 합니다.

    1) 타입을 먼저 계산하고

    2) 필드별 비교작업 수행





    하지만 이는 완벽하지 않습니다. equals 메서드를 오버라이딩 할때에는 hashcode라는 메서드도 같이 오버라이딩 해주어야 하기 때문입니다.


    예를 들어서 아래와 같이 hashcode를 사용하여 값을 얻을 수 있습니다. 그런데 내가 생성한 클래스로 hashcode 값을 얻어낼때에는 두 값이 일치 하지 않습니다. 이 또한 Object class의 hashcode 메서드를 사용했기때문입니다. 그래서 equals 메서드처럼 오버라이드해서 사용해야합니다.



    그래서 아래와같이 hashCode메서드를 오버라이드 해줍니다. 왜 저런 코드를 이용했을까요?

    우선 오버라이드 하는 베이슨 서로 다른 객체이더라도 같은 필드값을 가지고 있다면 같은 값을 리턴하도록 만들어주도록 하는 것입니다.

    그래서 int type의 표현 범위 내에서 고른 분포값을 return하도록 해주는 것이 가장 바람직합니다.




    http://iilii.egloos.com/4000476 이 링크에서 정리를 잘해주셨습니다.


    hashCode 구현 규약에는

    1. 두객체에 대해  equals가 true이면 두객체의 hasecode도 같아야합니다.(이 조건의 역설은 항상 참이지 않습니다.)

    2. 두 객체에 대해 equals가 false이면 가능하면 다른 값을 return하게 해주는것이 좋습니다.





    2.clone 메서드 : 객체를 복사하는 기능을 합니다.

    * 이 메서드는 복제 가능한 class에 대해서만 호출할 수 있습니다. 복제가능하다는 것은 Cloneable interface를 구현한다는것입니다.



    사용 예시는 다음과 같습니다. 당연히 복제해서 새로 생성한것이기때문에 단순히 =를 사용해서 한것(참조)과는 다른 결과를 뱉어내게됩니다.

    여기서 주의할점은 clone 메서드의 리턴 타입은 Object type으로 선언되어 있기 때문에 캐스팅을 해주어야합니다.




    내가 선언한 class를 clone하려면 이 역시 오버라이딩이 필요합니다. 아까 말했듯이 cloneable해야하기때문에 이 interface를 구현해주어야합니다.






    2.finalize 메서드 : 객체가 제거되기 전에 자동으로 호출되는 메서드입니다.

    자바는 c언어와 같이 소멸자같은건 없었습니다. 이참에 자바에서 객체가 제거되는 방법에 대해 알아봅시다.



    예를 들어서 아래와 같이 토끼라는 값을 가지는 객체를 생성하면 그 객체는 heap영역에 실제 데이터인 "토끼"가 존재하고 객체는 그 값을 참조하기 위한 값만을 가지고 있게 됩니다. 그렇기 때문에 이 참조값을 잃거나 변수가 사라지면 더이상 사용할 수 없게 됩니다.



    그럴때 이러한 값들을 가비지 컬렉터라는 모듈이 자바 가상기계 안에 존재하면서 주기적으로 실행(언제 실행되는지 모릅니다.)하여 힙에 사용하지 않는 가비지들을 제거하도록 하고 있습니다.




    아니 그럼 언제 실행될지도 모르는데 finalize 메서드는 왜 필요할까요? 예를 들어 아래와 같은 클래스가 있다고 하였을 때 시스템 자원을 할당 받았기 때문에 객체가 사라지기전 받았던 것을 토해야합니다. finalize 메서드를 오버라이드 해놓으면 가비지 컬렉터가 객체를 제거하기 전에 자동으로 그 메서드를 호출하게 되는것입니다.


    release라고 선언을 했어도 의도대로 그 흐름에 맞게 메서드가 실행된다는 보장이 없기때문에 이 부분을 finalize로 선언하는 것입니다.


                







    2.getClass 메서드 : 객체가 속하는 클래스의 정보를 알아내는 메서드입니다.


    사용예시는 아래와 같습니다.