final 예약어 질문입니다.

조회수 1998회
void method1()
{
    final int a = 10;
    TextView tv = (TextView)findViewByID(R.id.btn);
    tv.setOnClickListener(new OnClickListener() {
        @Override
        void onClick(View v)
        {
                a++;
        }
   });
}

여기서 변수 a가 final로 지정되지 않으면 생애주기 차이때문에 onClick 메소드 내에서 동일하게 사용할 수 없잖아요. 그럼 JVM이 여기서의 final을 static으로 변환하나요? 만약 static으로 변환한다면 메소드 method1이 종료되어도 변수 a는 메모리상에 살아있는등 완전히 static으로 선언했을때와 동일시해야 맞는 건가요? 감사합니다.

2 답변

  • 결론부터 이야기하면 method1() 함수가 호출된 이후에도 a의 값은 메모리 상에 존재합니다. 위키피디아의 내용을 인용하면 런타임에 final로 선언된 변수의 값을 내부 클래스의 필드로 캡쳐해서 저장하는 방식으로 동작한다.라고 되어 있습니다. method1()이 종료된 후에도 a의 값에 접근할 수 있는 이유는 이 부분을 참고하는게 좋을 것 같아요.

    When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. For scalar values, once it has been assigned, the value of the final variable cannot change. For object values, the reference cannot change. This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory.

    • (•́ ✖ •̀)
      알 수 없는 사용자
  • 자바에서 final 과 static은 상호 보완적 관계가 아닙니다.

    static

    static을 이해하기 위해서는 기본적으로 클래스와 인스턴스를 구분해야 합니다.

    클래스와 인스턴스와의 관계는 도면(클래스)과 도면에 의해 생성된 형상(인스턴스)으로 비유할 수도 있습니다. 이 때, 자바의 static은 의미적으로 인스턴스의 구성원(member)이 아닌, 클래스 자체를 위한 구성원(member)을 의미합니다.

    staitc으로 선언된 클래스 멤버 변수는 클래스가 메모리에 로딩되는 시점부터 클래스가 메모리상에서 언로딩될 때 까지의 생애주기를 가집니다. (하지만, 특별히 클래스를 언로딩하고자 노력하지 않는 다면, 대부분의 경우에서 클래스가 언로딩 되는 경우를 찾기 어렵습니다.)

    final

    자바의 final 키워드는 상수화한다는 의미입니다. 이는 변수와 상수차이인 데, 일반적인 상수 예를 들어 1, 2, 3과 같은 숫자가 있겠죠, 하지만 우리는 현실에서 중력가속도 상수 g 처럼, 문자를 사용하여 상수를 표현하기도 합니다. 프로그램에서도 변수처럼 생겼지만 상수로 인식하게 만드는 키워드가 final 입니다.

    위의 예에서 int a = 10의 경우 변수 a 입니다. 이 a를 상수로 바꾸는 방법이 final 키워드를 사용하는 것입니다. 이제 a는 더 이상 변수가 아님으로, 더 이상 변수의 생애주기를 가지지 않습니다. 우리가 프로그램을 작성할 때, 아무곳에서나 숫자 1,2,3 등을 쓰는 것과 같게 이해하면 됩니다.

    final은 상수화 한다의 의미는

    1. 값이 변할 수 없다.
    2. 변수의 생애주기를 벗어난다.
    3. 이름이 유효할 수 있는 범위(스코프)는 선언된 시점으로 부터, 선언된 블록이 해제될 때 까지로 확장됩니다.

    코멘트

    1. 마지막으로 위의 코드에서 a는 상수가 되었기 때문에, a++ 과 같은 연산을 할 수 없습니다.
    2. 기술적으로 보면, 메모리의 해제 시점은 자바의 다른 모든 참조가 그러하듯, 해당 개체의 참조가 0이 되는 순간 GargageCollector에 의해 제거됩니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)