안드로이드/자바 Variable 'data' is accessed from within inner class, needs to be declared final

안녕하세요. 개발자 드리머즈입니다.


안드로이드 개발을 하다보면 부실한 java 기본기가 보이기도 합니다. 이번 포스팅에서는 final에 대해 알아보겠습니다.


문제 상황


안드로이드에서 setOnClickListner를 구현하면서 익명 클래스(Anonymous Class)를 통해 onClick() 함수를 정의할 수 있습니다. 그런데 이 onClick() 함수 내부(=inner class)에서 익명 클래스의 외부에 존재하는 일반 변수(위의 사진에서 int data)에 접근하면 위의 사진과 같은 에러가 발생합니다.




문제 분석

에러는 아래와 같습니다.


Variable 'data' is accessed from within inner class, needs to be declared final


에러를 번역 하면 아래와 같습니다.

이너 클래스 내부에서 변수 'data'에 접근하고 있어, final 변수로 선언되어야 합니다.


왜 final 변수로 선언해야하는지 스택오버플로우에서 찾아봤습니다.

https://stackoverflow.com/questions/4785073/why-should-my-local-variables-be-final-to-be-accessible-from-anonymous-class/4785141#4785141


논란의 여지가 많은데 그 중에 위의 스택오버플로우에 있는 아래 답변이 좋은 것 같습니다.

이 답변은 https://www.developer.com/java/other/article.php/3300881의 내용을 언급했습니다.


As I told you in my earlier lessons on local classes, the methods in an anonymous class don't really have access to local variables and method parameters.  Rather, when an object of the anonymous class is instantiated, copies of the final local variables and method parameters referred to by the object's methods are stored as instance variables in the object.  The methods in the object of the anonymous class really access those hidden instance variables.

Thus, the local variables and method parameters accessed by the methods of the local class must be declared final to prevent their values from changing after the object is instantiated.


번역을 하면 아래와 같습니다.

앞선 로컬 클래스 강좌에서 말했듯이, 익명 클래스의 함수는 사실 로컬 변수와 함수 파라미터에 접근할 수 없습니다. 대신, 익명 클래스가 객체화 될 때, 그 객체의 함수가 참조하는 final 로컬 변수와 함수 파라미터는 그 객체의 객체 변수로 저장됩니다. 익명 클래스 객체 내부의 함수들은 사실은 그러한 숨겨진 객체 변수에 접근합니다.

따라서, 로컬 클래스의 함수가 접근하는 로컬 변수와 함수 파라미터는 클래스가 객체화된 이후로 값이 바뀌는 것을 방지하기 위해 반드시 final 변수로 정의되어야 합니다.


아직 확실하게 이해되지는 않네요. 간단할 줄 알았는데 자세히 이해하려면 프로그래밍 언어에 대한 심층적인 이해가 필요합니다.

일단은 익명 클래스의 함수에선 final이 붙지 않은 일반 변수는 (익명 클래스 외부에 존재하는) 로컬 변수에 접근이 불가능하다고 이해해야 겠습니다.


다음에 시간을 내서 좀 더 정리해야겠습니다.




작성자

Posted by 드리머즈

관련 글

댓글 영역