JVM

[Java] 메서드와 필드 접근: 런타임과 컴파일 타임의 차이

kyoulho 2025. 6. 5. 19:02

Java에서는 클래스에서 정의한 필드(변수)와 메서드(함수)에 접근할 때 서로 다른 원칙을 따릅니다. 메서드는 객체의 실제 타입(런타임 타입)을 따르고, 필드는 선언된 타입(컴파일 시점)을 따라갑니다. 

🔍 예제 코드 분석

class Parent {
    String str = "Parent";

    String getStr() {
        return str;
    }
}

class Child extends Parent {
    String str = "Child";

    String getStr() {
        return str;
    }
}

public class Main {
    public static void main(String[] args) {
        Parent parent = new Child();
        Child child = new Child();

        System.out.println(parent.getStr());
        System.out.println(child.getStr());
        System.out.println(parent.str);
        System.out.println(child.str);
    }
}

이 프로그램을 실행하면 어떤 결과가 출력될까요?

Child
Child
Parent
Child

🤔 왜 이런 방식으로 작동할까요?

Java에서 메서드 호출과 필드 접근이 서로 다른 방식으로 동작하는 이유는 다음과 같습니다:

  • 메서드 오버라이딩과 다형성
    • Java에서는 메서드를 런타임 시점에 실제 객체 타입에 따라 호출하여 다형성을 구현합니다.
    • 이것은 프로그램의 유연성과 확장성을 증가시키며, 메서드 호출 시 실제 객체가 가진 구체적인 동작을 보장합니다.
  • 필드 숨김(Shadowing)
    • 필드는 다형성을 따르지 않고, 필드 이름이 같을 경우 자식 클래스에서 부모 클래스의 필드를 숨기게 됩니다.
    • Java는 필드를 오버라이딩하지 않고 별개의 필드로 취급하여, 컴파일 시점에서 결정된 타입의 필드를 사용하도록 합니다.

즉, 메서드는 런타임의 실제 타입을 반영하여 프로그램의 유연성을 제공하지만, 필드는 컴파일 시점에서 정적으로 결정되어 성능과 명확성을 유지하기 위한 설계입니다.