LichKing 님의 말씀에 더 첨언해서 말씀드리면
익명클래스 에서 접근하려는 외부 클래스의 지역변수(외부 클래스의 멤버변수의 경우는 아닙니다. )의 경우는 final이어야 합니다 final 키워드를 쓰지 않으면 컴파일러가 잡아낸다는 거죠. java 7인가 8 인거 부터는 실질적으로 final이면 컴파일러가 알아서 판단합니다.(즉 final 키워드를 쓰지 않아도 실질적으로 final이면 그렇게 판단하고 컴파일 에러가 나지 않는다는 거죠)
익명클래스내에서 외부클래스의 지역변수가 왜 final 이어야 하는지에 대한 이유는 말씀드리기가 상당히 복잡합니다. 몇가지 사전 지식이 필요하죠
첫째, 변수 캡쳐와 클로저를 이해해야 합니다. 이것은 간단히 말하면 익명클래스에서 외부 클래스의 지역변수에 접근을 할수 있는 능력을 말하는 것이고, 더나아가 그렇게 접근한 외부클래스의 지역변수의 생명주기, 변경 가능성? 에 대한 이야기가 동반됩니다
둘째 자바에서의 캡쳔된 변수, 클로져 상황에서 해당 지역변수에 변경 가능성은 다른 언어(C#, 자바스크립트, C++)에 비해 다릅니다. 정확히 얘기하면 자바는 해당 지역변수에 대해 변경을 추적 할 수 가 없었습니다. 그래서 해당 지역변수가 변경될수 있음을 사전헤 차단하는 방법으로 클로저를 지원합니다. 즉 final 키워드를 명시적으로 표기 하겠끔 했죠, 앞서 말한것처럼 7?, 8? 부터는 실질적으로 final이면 해당 키워드를 안써도 되구요(final키워드를 안썼다고 변한다는건 아니니까요)
세번째 위의 내용으로만 보면 부족하는 능력의 클로저를 제공하는 자바가 못미더워 보입니다. 하지만
클로저 상황에서의 지역변수의 변경이 이루어짐이 필요한 상황은 드물며, 오히려 대부분 상황이 지역변수 변경이 이루어지며 안되는 상황이 더 많습니다. 그런 이유로 클로저를 제공하는 대부분의 언어들이 클로저를 소개할때 지역변수가 변경되지 않는 방식의 코드 작성방법을 소개합니다.
다른 언어의 클로저를 살펴보시길 추천합니다. 다른 언에서 클로저는 익명클래스가 아닌 익명함수, 람다에서 발생하며 지역변수가 변경되는 예제는 대부분 for문의 지역변수가 익명 함수 또는 람다에서 어떤식으로 동작하는지에 대한 소개가 나오니 그것을 보시면 이해가 될겁니다.