티스토리 뷰

발생일: 2009.12.08

문제:
클래스 A를 상속받는 클래스 B가 있다.
테스트를 위해서 각각의 클래스에 main 메서드를 작성해놨다.

class A {
    public static void main(String[] args) {}
}

class B extends A {
    public static void main(String[] args) {} // overriding 하려고 시도
}

이런 식이다.

이클립스에서 이 내용을 작성하고 있었는데,
분명 B 클래스의 main 메서드는, A 클래스의 것을 오버라이딩한 게 맞을 텐데,
이상하게 메서드 앞에 오버라이드 됐다는 아이콘이 표시되지 않는다.

어라? 스태틱 메서드는 오버라이딩 되지 않는 건가?


해결책:
검색해보니, static 메서드는 Overriding 할 수 없다고 한다.
대신 스태틱 메서드에서의 오버라이딩은 Hiding 이라고 한다.

JVM 이 메서드를 호출할 때,
instance method 의 경우 런타임 시 해당 메서드를 구현하고 있는 실제 객체를 찾아 호출한다. (다형성)
하지만 class method (static method)의 경우, 컴파일 시점에 선언된 타입의 메서드를 호출한다.
컴파일러와 JVM 모두 클래스(스태틱) 메서드에 대해서는 실제 객체를 찾는 작업을 시행하지 않기 때문이다.
(즉, 스태틱 메서드에 대해서는 다형성이 적용되지 않는다)

아래 코드를 가지고 테스트해보면 쉽게 이해가 된다.

    class A {
        public static void classMethod() {
            System.out.println("classMethod() in A");
        }
       
        public void instanceMethod() {
            System.out.println("instanceMethod() in A");
        }
    }
   
    class B extends A {
        public static void classMethod() {
            System.out.println("classMethod() in B");
        }
       
        public void instanceMethod() {
            System.out.println("instanceMethod() in B");
        }
    }
   
    class Test {
        public static void main(String args[]) {
            A a = new B();
            a.classMethod(); // classMethod() in A 가 출력된다.
            a.instanceMethod(); // instanceMethod() in B 가 출력된다.

            // static method 를 포함하고 있는 클래스로 선언할 경우 호출할 수 있다.
            ((B) a).classMethod();
// classMethod() in B 가 출력된다.
        }
    }
  

몇 가지 사용에 대한 팁을 제시하자면,..
    1. 오버라이드된(하이딩 된) 스태틱 메서드를 정확하게 호출하려면  메서드가 포함된 실제 객체로 선언해야 한다.
    2. 웬만하면, 하이딩의 사용은 피하는 게 좋겠다.


상세한 내용은 아래 포스트를 참고하자. (꼭 읽어보길 권한다)
반응형
댓글
공지사항