3 minute read

인스턴스 변수 (non-static 필드)

특징

  • 클래스의 인스턴스마다 할당된 값이 다르다.
  • 메서드, 생성자, 코드 블록 바깥에서 선언된다.
  • 객체의 상태를 정의한다.

JVM에서 할당되는 위치

  • Heap 영역에 할당된다.
  • 객체가 new 키워드로 인스턴스화 될 때 생성된다.
  • 객체가 참조되거나 메모리 상 존재하는 경우에 유효하다.
  • 객체가 garbage collect되면 제거된다.

코드 예시

public class Student {
    // Instance Variable
    private String name;
    private int age;

    // ... rest of the class
}

클래스 변수 (static 필드)

특징

  • 클래스로부터 생성되는 인스턴스의 개수에 상관 없이 하나만 존재한다.
  • 인스턴스가 아닌 클래스 그 자체에 속한다.

JVM에서 할당되는 위치

  • Method 영역에 할당된다.
  • 클래스가 JVM에 처음 로딩될 때 생성된다.
  • 프로그램이 종료되거나 JVM이 셧다운되기 전까지 유효하다.

코드 예시

public class Student {
    // Class Variable (Static Field)
    public static String schoolName = "ABC High School";

    private String name; // instance variable
}
  • ➕ 인스턴스에서 가져다 쓸 수 있지만, 쓰지 마세요
    • 기술적으로 인스턴스에서 클래스 필드를 사용하지 못하는 건 아니다.
    • 인스턴스에서 정적 필드를 쓰면 “이거 인스턴스 필드인가?”하고 헷갈릴 위험이 있다.
    • final을 쓰지 않으면 인스턴스가 정적 변수를 수정해버릴 위험도 있다!
      class MyClass {
          static int count = 0;
      }
        
      public class Main {
          public static void main(String[] args) {
              MyClass obj = new MyClass();
                
              // These all work technically:
              obj.count = 5;           // Through instance
              MyClass.count = 5;       // Through class name (recommended)
          }
      }
    
  • ➕ JVM에서 Method 영역의 위치는?
    • 전통적인 JVM에서 Method 영역은 Heap과 구분되어 있었다.
    • 그러나 HotSpot JVM같은 현대 JVM에서 Method 영역은 Heap의 일부로 구현되고는 한다.
    • 개념적으로 이해할 때는 “Method 영역에 있다”고 하는 게 맞으나, 기술적으로 이해할 때는 “JVM의 garbage collector와 Heap이 관리하는 메모리 공간”이라고 하는 게 맞다.

지역 변수

특징

  • 메서드, 생성자, if문의 블록 등에서 선언된다.
  • 자신이 선언된 코드 블록 내에서만 사용될 수 있으며, 인식될 수 있다.

      if (condition) {
      	int myLocalVal = 1;
      }
        
      // 인식 못 함
      int whatIsIt = myLocalVal;
    

JVM에서 할당되는 위치

  • Stack 영역에 할당된다.
  • 지역 변수가 선언된 코드 블록이 실행될 때 생성된다.
  • 지역 변수가 선언된 코드 블록을 빠져 나오는 즉시 제거된다.
  • 다른 변수들에 비해 생애주기가 유달리 짧은 편이다.

코드 예시

public void calculateTotal() {
    // Local Variable
    int total = 0;
    for (int i = 0; i < 10; i++) { // 'i' is also a local variable
        total += i;
    }
} // 'total' and 'i' are destroyed here as the stack frame is popped.
  • ➕ if문의 코드 블록도 중괄호로 이뤄져 있으니까 메서드라고 볼 수 있는 것 아닌가요?
    • 결론: 둘이 다르다.
    • 정의와 목적
      • 메서드: 행동을 정의한다.
      • if 구문: 조건에 따라 호출된다.
        // METHOD - defines behavior, can be called
        public void myMethod() {
            System.out.println("I'm a method");
        }
              
        // IF BLOCK - conditional execution, cannot be called
        if (condition) {
            System.out.println("I'm just a code block");
        }
      
    • 호출
      • 메서드는 다른 코드에서 호출될 수 있다. myMethod();
      • if 블록은 조건이 참인 경우 자동적으로 실행될 뿐, 호출 매커니즘이 없다.
    • 파라미터와 반환 값
      • 메서드는 파라미터와 반환값이 있다.
      • if문은 둘 다 없다.
        // METHOD - can have parameters and return values
        public int calculate(int a, int b) {
            return a + b;
        }
              
        // IF BLOCK - no parameters, no return values
        if (x > 5) {
            // Just executes code, can't return anything
        }
      
    • 둘의 유일한 공통점은 “변수에 대한 범위를 생성한다” 뿐이다.

        public void example() {
            if (condition) {
                int localVar = 10; // Local to if block
            }
                  
            public void someMethod() {
                int methodVar = 20; // Local to method
            }
        }
      

파라미터

특징

  • 메서드에 값을 전달할 목적으로 선언된다.
  • 메서드의 stack frame의 일부이다.

JVM에서 할당되는 위치

  • Stack 영역에 할당된다.
  • 메서드가 호출될 때 생성되고 메서드의 사용이 종료되는 즉시 제거된다.
  • 지역 변수는 코드 블록, 파라미터는 메서드 블록이라는 점을 제외하면 둘의 생애주기가 동일하다.

코드 예시

public void setAge(int studentAge) { // 'studentAge' is a parameter
    // studentAge is accessible here like a local variable
    this.age = studentAge;
}
  • ➕ “메서드의 stack frame의 일부”라는 말의 의미
    • Call Stack(Stack): JVM이 메서드의 호출과 메서드의 지역 데이터를 추적하는 메모리의 공간. LIFO 방식으로 작동한다.
    • Stack Frame(Activation Record): 메서드가 호출될 때 마다 Call Stack에 쌓이는 메모리의 블록. 메서드를 호출하여 실행할 때 필요한 모든 데이터를 포함한다. 메서드가 끝나면(반환하면) 전체 Stack Frame이 Stack에서 제외되고 삭제된다.
    • Stask Frame에 파라미터(아규먼트), 지역 변수, 반환 주소(메서드 호출이 완료될 수 코드의 실행을 재개할 위치), “this”에 대한 참조(인스턴스 메서드인 경우. 현재 객체를 의미함), 피연산자 Stack(JVM이 계산할 때 사용함)

Categories:

Updated: