7.1 필드

jh·2022년 1월 26일
0

Do it! 자바 완전 정복

목록 보기
56/70

필드field는 '클래스에 포함된 변수'로 객체의 속성값을 지정할 수 있다. 필드는 지역 변수 local variable와 구분해야 한다. 지역 변수는 '메서드에 포함된 변수'를 말한다. 즉, 필드와 지역 변수는 어떤 중괄호 안에 선언됐는지에 따라 구분할 수 있다. 클래스의 중괄호 안에 선언된 변수를 '필드', 메서드의 중괄호 안에 선언된 변수를 '지역 변수'라고 생각하면 된다. 필드와 지역 변수의 가장 큰 차이점은 생성되는 메모리의 위치다. 필드는 힙 메모리의 객체 내부, 지역 변수는 스택 메모리에 생성된다. 스택 메모리에 저장되는 변수는 때가 되면 자바 가상 머신이 자동으로 삭제하지만, 힙 메모리의 객체 안에 저장되는 필드는 객체가 사라지지 않는 한 절대로 삭제되지 않는다.

그렇다면 스택 메모리의 변수는 언제 자동으로 삭제될까? 자신이 선언된 메서드의 중괄호가 닫혀 메서드가 종료되면 그 메서드 안에 선언된 모든 지역 변수가 메모리에서 통째로 삭제된다. 다음 예를 살펴보자.

    int m = 3;   // 상위 중괄호가 클래스일 때는 필드
    int n = 4;    // 상위 중괄호가 클래스일 때는 필드
    void work1() {
        int k = 5; // 상위 중괄호가 메서드일 때는 지역 변수 
        System.out.println(k);
        work2(3);
    }
    void work2(int i) { // 상위 중괄호가 메서드일 때는 지역 변수
        int j = 4;      // 상위 중괄호가 메서드일 때는 지역 변수
        System.out.println(i + j);
    }   
} 

클래스 A에는 필드 m,n과 메서드 work1(), work2()가 있다. 메서드는 '리턴 타입 메서드 명(){...}의 형태를 띤다. work1()메서드 안에는 지역 변수 k를 선언해 사용했고, work2()메서드에서는 지역 변수 i와 j를 선언해 사용했다. 여기서 소괄호 안의 변수 i도 메서드의 중괄호 안에서 정의한 것으로 간주하면 된다. 이제 다음과 같이 클래스 A의 객체를 선언하고, 내부의 필드와 메서드를 사용해보자.

A a= new A()
System.out.println(a.m); // 3
System.out.println(a.n); // 4
a.work1(); // 5 -> 7

먼저 클래스 A로 객체를 생성하고 참조 변수명은 a로 선언했다. 그리고 참조 변수 a와 포인트 연산자(.)를 이용해 필드 m과 n의 값을 출력했다. 마지막으로 work1() 메서드를 호출했다. work1() 메서드 안에서 work2(3)과 같이 work2()메서드를 호출하며 입력매개변수로 3을 넘겨 work2()메서드의 입력매개변수인 int i = 3이 되도록 했다. 메서드는 아직 제대로 배우지 않았으므로 이해되지 않는 부분이 있더라도 일단 넘어가자. 그래도 어느 정도의 흐름은 파악할 수 있을 것이다. 이제 메모리를 살펴보자.

먼저 객체를 생성했으므로 힙 메모리에는 클래스 A의 객체가 생성된다. 이 객체 안에는 클래스의 멤버인 필드 m,n과 메서드 work1(), work2()가 저장돼 있고, 각 필드값으로는 3과 4가 저장돼 있다. 스택 메모리를 살펴보면 참조 변수 a에는 객체의 위칫값이 저장되어 있다. work1() 메서드가 호출되면 work1() 메서드 안에 정의된 지역 변수 k가 스택 메모리에 저장되고 (int k = 5;), work1() 메서드 안에서 work2() 메서드가 호출되면 work2() 메서드 안에서 정의된 지역 변수 i,j가 스택 메모리에 저장된다(int i = 3, int j = 4). 정의된 메서드의 중괄호에 해당하는 범위를 메모리에서는 '프레임 frame'이라고 부르는데 해당 메서드의 실행이 종료되면 자바 가상 머신은 해당 메서드의 프레임을 통째로 삭제한다. work1() 메서드 안에서 work2()메서드를 호출했기 때문에 work2() 메서드가 호출된 시점에서 메모리에는 work1() 프레임과 work2() 프레임이 모두 존재한다. 이후 work2()가 완료되면 work2() 프레임이 모두 삭제되며, work1() 메서드도 완료되면 work1()프레임도 삭제된다.

실습

// 클래스 생성
class A {
    int m = 3; // 필드
    int n = 4; // 필드
    void work1(){
        int k = 5;
        System.out.println(k);
        work2(3); // work2() 안에 정의된 지역 변수를 스택 메모리에 추가
    }
    void work2(int i) { // 인수를 변수 i에 대입해 입력매개변수로 활용
        int j = 4; // 지역 변수
        System.out.println(i + j);
    }
}
        public class jh {
            public static void main(String[] args) {
                // 클래스로 객체 생성
                A a = new A();
                // 필드값 출력
                System.out.println(a.m); // 3
                System.out.println(a.n); // 4
                // 메서드 호출 
                a.work1(); // 5 -> 7
            }
        }

결과

profile
코딩 공부 중...

0개의 댓글