adSense 900*70


java.lang.Object series -1 JAVA - Basic

Object Class는 Java를 알고 있는 사람이라면 다들 알고 있을것이다. 가장 최상위 Class이고 모든 Class들은 Object Class를 상속받는 다는 것인데 그렇지만 실제로 이를 확인 해볼 수 있는 방법은 뭐가 있을까? 상속받는 다니 "아~ 그렇군"하고 그냥 넘어가는 경우가 대부분일 것같다. 나도 그런 경우였다. 하지만 이번에 좀 제대로 공부하고자 처음부터 하나씩 제대로 확인을 하고 넘어가볼려고 한다.

아래와 같은 간단한 코드가 있다. 흔히 보는 HelloWorld 예제인데.단순히 HelloWorld만 화면에 보여주는 예제일 수도 있고, 그렇지 않을 수 도 있다. 아래 예제를 통해 해당 Class가 정말 Object 클래스를 상속받는지 확인 해봅시다.

Class HelloWorld{
public static void main(String[] ar){
System.out.println("Hello World");
}
}
대부분의 경우, 나도 그랬고, 이클립스를 사용할 경우 저장만 하면 자동으로 해당 클래스가 컴파일이 된다.즉, HelloWorld.class라는 클래스 파일(bytecode파일)이 생성된다. 그리고 실행 버튼만 누르면 실행이 된다. 하지만 이번엔 이클립스를 사용하지 않고 Notepadd++를 사용하여 해당 코드를 작성하고 컴파일 실행해볼려고 한다. 실행하면서 실제로 Object가 상속이 된건지 아닌지도 확인 해 보고 말이다.
컴파일시에 -verbose 옵션을 주어 컴파일하게 되면 필요한 클래스들을 로드를 하게 된다. 즉 위의 클래스에 들어가 있거나 상속 받은 클래스들을 모두 ClassLoader가 로딩을 해주게 되는 것이다.
컴파일 결과는 아래와 비슷하게 나올텐데, 결과를 살펴보면 java.lang.Object.class를 로드를 한것을 볼 수 있다. 근데 위의 코드에서는 java.lang.Object는 import를 하거나 코드내에서 쓴 적이 없는데 컴파일시에 왜! 로드를 하는 것일까? 바로 HelloWorld 클래스가 Object 클래스를 상속받기 때문이다. 뭐 나머지 클래스들은 왜 로드가 되는지는 이미 코드안에 다 들어있다. io 관련 클래스들이 로드된 것을 볼 수 있는데 이는 System클래스의 멤버변수 out이 PrintStream 타입이고 PrintStream 클래스는 OutputStream, FilterOutputStream을 상속받기 때문에 로드가 된것이다. 따라서 컴파일시에는 load되는 클래스가 상속받는 클래스들 역시 로드가 되는 것을 알 수 있다. 

[parsing started d:\dev_\java_practice\my\HelloWorld.java]
[parsing completed 31ms]
[search path for source files: .]
[search path for class files: D:\dev_\java\jdk1.6.0_25\jre\lib\resources.jar,D:\
dev_\java\jdk1.6.0_25\jre\lib\rt.jar,D:\dev_\java\jdk1.6.0_25\jre\lib\sunrsasign
.jar,D:\dev_\java\jdk1.6.0_25\jre\lib\jsse.jar,D:\dev_\java\jdk1.6.0_25\jre\lib\
jce.jar,D:\dev_\java\jdk1.6.0_25\jre\lib\charsets.jar,D:\dev_\java\jdk1.6.0_25\j
re\lib\modules\jdk.boot.jar,D:\dev_\java\jdk1.6.0_25\jre\classes,D:\dev_\java\jd
k1.6.0_25\jre\lib\ext\dnsns.jar,D:\dev_\java\jdk1.6.0_25\jre\lib\ext\localedata.
jar,D:\dev_\java\jdk1.6.0_25\jre\lib\ext\sunjce_provider.jar,D:\dev_\java\jdk1.6
.0_25\jre\lib\ext\sunmscapi.jar,D:\dev_\java\jdk1.6.0_25\jre\lib\ext\sunpkcs11.j
ar,.]
[loading java\lang\Object.class(java\lang:Object.class)]
[loading java\lang\String.class(java\lang:String.class)]
[checking HelloWorld]
[loading java\lang\System.class(java\lang:System.class)]
[loading java\io\PrintStream.class(java\io:PrintStream.class)]
[loading java\io\FilterOutputStream.class(java\io:FilterOutputStream.class)]
[loading java\io\OutputStream.class(java\io:OutputStream.class)]
[wrote d:\dev_\java_practice\classes\HelloWorld.class]

다음은 Object 클래스의 메서드를 상속받고 가져다 쓸 수 있다는 것이다. 그럼 Object 클래스에는 어떤 메서드들이 있을까? 
일단 위의 링크를 타고 들어가서 한번 보면 Object클래스에 대한 설명이 나온다. 최상위 클래스, 배열을 포함한 모든 클래스들의super class, 배열을 포함한 모든 객체에선 Object 클래스의 메서드를 구현한다. 라고 나온다. 
wait, notify, notifyAll 그리고 getClass 메서드들 요것들은 final이라서 상속은 받되 overriding이 안된다. 하지만 나머지 메서드들 
clone, toString, equals, hashCode, finalize. 요 메서드들은 상속되고 또한 overriding이 된다. 그런데... 왜? wait, notify, notifyAll 그리고 getClass메서드는 overriding을 할 수 없게 final로 막아놓았을까? 그건 나도 아직 모른다. @@;;;
모르는 부분이 나오니 급 피곤해지네 낼 이어서 써야겠다.

getClass 메서드를 final로 막아놓은 이유를 생각해보건데... getClass로 로딩하는 객체는 프로그램 실행시의 해당객체의 Type, 즉, Class이다. 그러면 getClass를 재정의 할 수 있게 해놓았다면 어떤일이 발생할 수 있을까? 자칫 잘못하면 졸라 복잡한 문제가 생길 수도 있다는 거다. 음~ 지금까지의 생각은 그렇다는 것. 
좀 더 확실히 정리가 되고 하면 다시 써야겠다.


덧글

댓글 입력 영역


side adsense

adSense 900*70