[JAVA] 자바 클래스 내부 구성 - 필드

    728x90

    안녕하세요

    로로봉입니다 : )

    자바에서 필드에 대해 알아보도록 하겠습니다.


    1) 필드와 지역 변수의 구분

    필드는 클래스에 포함된 변수로 객체의 속성값을 지정할 수 있습니다. 필드는 지역 변수와 구분하여 사용해야 합니다.

    지역 변수는 메서드에 포함된 변수를 말합니다. 필드와 지역 변수는 어떤 중괄호 안에 선언됐는지에 따라 구분할 수 있습니다.

    클래스의 중괄호 안에 선언된 변수를 '필드', 메서드의 중괄호 안에 선언된 변수를 '지역 변수'라고 생각하면 됩니다.

    필드와 지역 변수의 가능 큰 차이점은 생성되는 메모리의 위치입니다.

    필드는 힙 메모리의 객체 내부, 지역 변수는 스택 메모리에 생성됩니다.

    스택 메모리에 저장되는 변수는 시간이 지나면 자바 가상 머신이 자동으로 삭제하지만, 힙 메모리의 객체 안에 저장되는 필드는 객체가 사라지지 않는 한 절대로 삭제되지 않습니다.

    [ 그림 1 : 필드와 지역 변수의 저장 위치 ]

    그렇다면 스택 메모리의 변수는 언제 삭제되는지 알아보겠습니다.

    지역 변수가 선언된 메서드의 중괄호가 닫혀 메서드가 종료되면, 그 메서드 안에 선언된 모든 지역 변수가 메모리에서 통째로 삭제됩니다.

    class Test {
       int a = 1;
       int b = 2;
       void run1() {
          int c = 5;
          System.out.println(c);
          run2(3);
       }
       void run2(int i) {
          int j = 4;
          System.out.println(i + j);
       }
    }

    클래스 Test에는 필드 a, b와 메서드 run1(), run2()가 있습니다. run1 메서드에서는 지역변수 c를 선언해 사용했고, run2 메서드에서는 지역변수 i와 j를 선언해 사용했습니다.

    여기서 소괄호 안의 변수 i도 메서드의 중괄호 안에서 정의한 것으로 간주하면 됩니다.

    이제 아래와 같이 클래스 Test의 객체를 선언하고, 내부의 필드와 메서드를 사용해보겠습니다.


    Test t = new Test();
    System.out.println(t.a);
    System.out.println(t.b);
    t.run1();
    
    //// 결과 ////
    1
    2
    5
    7

    설명을 하자면 먼저 클래스 Test를 객체로 생성하고, 참조 변수명은 t로 선언했습니다.

    그리고 객체의 필드 a, b에 접근하기 위해 포인트 연산자(.)을 이용하여 a, b 값을 출력했습니다.

    run1을 실행하면 int c에 있는 5가 출력되고, run2 메서드가 실행되어 int i = 3과 int j = 4를 더한 7이 출력되게 됩니다.

    이제 위의 코드가 메모리에 어떻게 저장되는지 알아보겠습니다.

    [ 그림 2 : 필드, 메서드, 지역 변수의 메모리 구조 ]

    먼저 객체를 생성했으므로 힙 메모리에는 클래스 Test의 객체가 생성됩니다.

    이 객체 안에는 클래스의 맴버인 필드 a, b와 메서드 run1(), run2()가 저장되고, 각 필드값에는 1, 2가 저장됩니다.

    스택 메모리를 살펴보면 참조 변수 t에는 객체의 위치 정보가 저장됩니다.

    run1() 메서드가 호출되면 메서드 안에 정의된 지역 변수 c가 (int c = 5) 스택 메모리에 저장됩니다.

    그 후에 run2() 메서드가 호출되고 run2() 메서드 안에 정의된 지역 변수 i, j가 (int i = 3, int j = 5) 스택 메모리에 저장됩니다.

    정의된 메서드의 중괄호에 해당하는 범위를 메모리에서는 프레임이라고 부르는데, 해당 메서드의 실행이 종료되면 자바 가상 머신은 해당 메서드의 프레임을 통째로 삭제합니다.

    run1() 메서드 안에서 run2()메서드를 호출했기 때문에 run2()메서드가 호출된 시점에서 매모리는 run1() 프레임과 run2() 프레임이 모두 존재합니다.

    이후 run2() 메서드가 완료되면 run2() 프레임이 모두 삭제되고, run1() 메서드도 완료되어 프레임이 삭제됩니다.


    2) 필드와 지역 변수의 초기값

    필드와 지역 변수의 또 다른 차이점은 초기 값에 있습니다. 필드는 직접 초기화하지 않아도 강제로 초기화 됩니다.

    반면, 지역 변수는 직접 초기화하지 않으면 저장 공간이 빈 공간 그대로 있어 값을 출력하고자 할 때 오류가 발생합니다.

    필드와 지역 변수의 차이가 아니라 각각이 위치하는 메모리 영역의 특징이라고 볼 수 있습니다.

    힙 메모리에는 빈 공간이 저장될 수 없기 때문에 힙 메모리에 위치하는 필드는 강제로 초기화 되는 것이고, 스택 메모리는 강제로 초기화되지 않아 스택 메모리에 저장되는 지역 변수는 초기화를 직접 해주어야 합니다.

    [ 그림 3 : 필드와 지역 변수의 초기화 ]

    예제를 실행하여 알아보도록 하겠습니다.

    class Test {
       int a;
       int b;
       void run1() {
          int c;
          //System.out.println(c);	// 지역 변수를 초기화 하지 않고 출력을 시도해서 오류 발생
       }
    }
    
    Test t = new Test();
    System.out.println(t.a);
    System.out.println(t.b);
    t.run1();
    
    // 결과
    0
    0

    위의 소스를 보시면 객체로 생성된 t.a 와 t.b 는 힙 영역에 저장되므로 별다른 초기화 없이도 0으로 강제 초기화가 됩니다.

    반면 run1() 메서드 안에 선언된 int c 지역 변수는 c = 0; 이라든지 별다른 초기화 처리를 하지 않고 출력을 시도해 오류가 발생하는 것을 볼 수 있습니다.

    지역변수는 반드시 초기화 작업을 직접 해주어야합니다.

    이렇게 JAVA에서 사용하는 클래스의 필드에 대해 알아보았습니다.

    다음 포스팅에서는 메서드에 대해 좀 더 자세히 알아보도록 하겠습니다.

     

    좋아요 ♥ + 구독 부탁드립니다 : )

    728x90
    반응형

    댓글