ローカルクラスがローカル変数を参照する場合、final でなければならない

JLS2 8.1.2 より。ローカルクラスの生存期間はそれを囲むブロックの生存期間より長い可能性があるから。

class LocalClass {
    void test(final int arg) {
        final int i = 100;

        class Inner {
            // Inner クラスのコンストラクタは
            // 外側のオブジェクトへの参照と
            // arg の値を引数として受け取り、隠しフィールド変数
            // this$0 と val$arg へ格納する。

            int test1() {
                // この場合、定数 100 を返す。
                return i;
            }

            int test2() {
                // この場合、隠しフィールド変数 val$arg の値を返す。
                return arg;
            }
        }
    }

    static void static_test(final int arg) {
        class StaticInner {
            // ちなみに、static コンテキストの内部クラスは
            // 外側のオブジェクトへの参照は持たない。
            int test() {
                return arg;
            }
        }
    }
}