지역변수에 final이 붙을 때의 의미에 대해
만일 아래 코드에서 mText에 final이 붙지 않은 상태에서
layout.setOnTouchListener()에서 mText를 사용하고자 하면
컴파일 단계에서 아래와 같은 에러가 발생한다.
Cannot refer to a non-final variable mText inside an inner class defined in a different method
이유가 뭘까? 같은 onCreate() 메소드 안에 있는 변수인데...?
그 이유는...
public class AAAActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView mText = (TextView)findViewById(R.id.textV);
LinearLayout layout = (LinearLayout)findViewById(R.id.linear);
layout.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent e) {
mText.setText("Touched"); //에러 발생
return true;
}
});
}
- mText는 전역변수도 아니고, onTouch()의 지역 변수도 아니며 onCreate()의 지역 변수로 선언되어 있다.
- 리스너인 onTouch()는 onCreate()에 속한 지역 메서드가 아니라는 점을 주의해야 한다. onCreate()가 실행시에 onTouch()가 같이 실행되는 것이 아니라 터치 이벤트 발생시 실행할 메스드로 등록만 할 뿐이다.
- 에러가 발생하는 이유는 mText 변수는 onCreate()가 리턴되면 사라지는 지역 변수이다. 반면 onTouch()는 터치 리스너로 등록되며 onCreate()가 리턴된 후에라도 이벤트가 발생하면 언제든지 호출될 수 있다. onTouch()가 호출되었을 때는 mText 변수가 존재하지 않으므로 mText의 실제값을 참조할 길이 없다. 미래에 호출될 리스너에게 현재의 지역 변수값을 전달하는 것은 불가능하다.
- 그런데 여기서 지역 변수에 final을 붙이면 더 이상 변경할 수 없는 상수가 되므로 onTouch()를 등록하는 시점에 그 값을 분명히 전달할 수 있다.
'Android' 카테고리의 다른 글
Parcelable 개념(객체 직렬화) 정리 및 bad array lengths 에러 해법 (0) | 2015.12.08 |
---|---|
구글 제공 API 데모(샘플) 소스 이클립스에서 import 하는 법 (0) | 2015.11.19 |
xml의 layout_gravity에 대한 숨겨진 규칙 (0) | 2015.11.16 |
안드로이드 타이틀바 없애고 전체화면, 화면 가로로(혹은 세로로) 고정하는 법 (0) | 2015.11.16 |
안드로이드 xml에 공백 및 특수 문자 넣기 (0) | 2015.11.10 |