Java/The Java

[Java] 클래스 멤버는 왜 인스턴스 멤버를 참조할 수 없을까?

어썸오184 2020. 12. 30. 14:23
728x90
반응형

클래스 멤버와 인스턴스 멤버 간 참조 관계


클래스 멤버(스태틱 변수, 스태틱 메서드)는 인스턴스 멤버를 사용할 수 없습니다. 아래 예시를 보시죠

static 예약어가 사용된 클래스 멤버에서 인스턴스 메서드를 호출하거나 인스턴스 변수를 사용하려고하면 빨간줄이 그어지면서 컴파일 에러가 발생합니다.

반면 인스턴스 메서드에서 클래스 변수를 사용하거나 클래스 메서드를 호출하는데는 아무런 문제가 없죠.

왜 이런 일이 발생할까요? 이는 클래스 멤버와 인스턴스 멤버가 생성되는 시기와 관련이 있습니다.

 

JVM 메모리 구조


우선 JVM의 메모리 구조를 살펴봅시다. JVM의 Runtime Data Area는 서로 다른 용도를 가진 영역으로 구분되어 있습니다.

그 중 메서드 영역, 호출 스택, 힙에 대해 살펴보겠습니다.

JVM 메모리 구조

 

  • 메서드 영역(method area)
    • 프로그램 실행 중에 어떤 클래스를 만나게 되면, JVM은 해당 클래스의 바이트코드를 읽어서 클래스에 대한 정보를 이곳에 저장합니다. 이 때, 그 클래스의 클래스 변수도 이 영역에 함께 생성됩니다.
  • 힙(heap)
    • 인스턴스가 생성되는 공간입니다. 인스턴스가 생성될 때, 인스턴스에 대한 정보들은 이곳에 저장됩니다.
  • 호출스택(call stack or execution stack)
    • 호출스택은 메서드가 호출될 때, 메서드의 실행에 필요한 데이터를 위해 메모리 공간이 할당됩니다.. 이 메모리는 메서드가 실행되는 동안 지역변수들과 연산의 중간 결과 등을 저장하는데 사용됩니다. 메서드가 작업을 마치면 할당되었던 메모리 공간은 반환되어 비워집니다.

클래스 멤버는 클래스가 메모리에 로딩될 때 생성됩니다. 인스턴스 멤버는 인스턴스가 생성될 때, 메모리에 로딩되고 생성됩니다. 즉 이 둘은 메모리에 생성되는 시기와 장소가 다릅니다.

 

근데 잘 생각해보면, 인스턴스가 생성되는 시점에는 항상 클래스가 메모리에 로딩되어 있음이 보장됩니다. 클래스가 존재하지 않는데 그 클래스의 인스턴스를 생성할 수는 없죠.

이 시점에 클래스도 생성되고 인스턴스도 생성됨

 

하지만 클래스의 생성이 인스턴스의 존재를 보장하지는 않죠. 

인스턴스는 필요없음

그러니 인스턴스 멤버는 클래스 멤버를 사용해도 아무런 문제가 없습니다. 이미 클래스는 존재하니까요!

하지만 클래스 멤버는 인스턴스 멤버를 사용할 수 없죠. 인스턴스가 존재하지 않을 수도 있으니까요.

 

참고자료

자바의 정석(남궁성 저)

728x90
반응형