Java のローカル内部クラスや無名内部クラスから外部のローカル変数にアクセスする

Java で Swing を使ってると無名内部クラス (anonymous inner class) をしばしば用いることになると思います。 例えば SwingUtilities.invokeLater メソッド に渡す Runnable オブジェクト は無名内部クラスとして生成することが多いのではないでしょうか?

そのような無名内部クラスやローカル内部クラス (local inner class) からは、そのクラスが定義されているスコープ内のローカル変数 (局所変数) やメソッドパラメータにアクセスできないものだと思っていまして、「アクセスできれば便利なのになー」 とずっと思っていました。 が、実はローカル変数へのアクセスはできるということを知ったのでメモ書きしておきます。

public class Test {
    
    public static void main( String[] args ) {
        // 無名内部クラスからアクセスされるローカル変数
        final int extVar = 100;
        // 無名内部クラス
        new Runnable() {
            @Override
                public void run() {
                    // 無名内部クラスの外部で、かつ無名内部クラスが定義されて
                    // いるスコープ内のローカル変数にアクセスする
                    System.out.println( extVar );
                }
        }.run();
    }

}

ただし、アクセスできるのは final 修飾子が付けられた変数だけ です。 final 修飾子が付けられていない変数へのアクセスは以下のようなコンパイルエラーを引き起こします。

Cannot refer to a non-final variable variableName inside an inner class defined in a different method

参考文献

プログラミング言語Java (The Java Series)

プログラミング言語Java (The Java Series)

  • 作者: ケン・アーノルド,ジェームズゴスリン,デビッドホームズ,柴田芳樹
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2007/04
  • メディア: 単行本
  • 購入: 38人 クリック: 1,044回
  • この商品を含むブログ (71件) を見る

Amazon.co.jp では 「翻訳がひどい」 ということであまり評価は高くありません。 実際、翻訳がひどくて全く意味を理解できない箇所もないことはないのですが、まあ読み辛いものの意味は理解できるのが大部分ですし、内容的には良いと思います。