Effectively final

先日のJJUGナイトセミナー(前半資料/後半資料)でfianlつけていなくてもfinalとみなされるEffectively finalというものがJava 8から導入されるという話を聞いた。(前半資料16pに出てくる「実質的final」)

public class JavaApplication1 {
    public static void main(String[] args) {
        String hoge = "こんにちは世界。";
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println(hoge);
            }
        };
        r1.run();

        Runnable r2 = () -> {
            System.out.println(hoge);
        };
        r2.run();
    }
}

上みたいなfinalの付いていない変数(String hoge)も代入していなければfinalとみなして匿名クラス、ラムダ式の中で使えるようになったとのこと。

 

ちなみにJava 7までだと下みたいにエラー。

a

 

final付いていないけどfinal扱いなので再代入したらだめ。

String hoge = "こんにちは世界。";
        hoge ="こんばんわ";
        Runnable r1 = new Runnable() {
            @Override

とか

            public void run() {
                hoge ="こんばんわ";
                System.out.println(hoge);
            }

とか

        Runnable r2 = () -> {
            hoge ="こんばんわ";
            System.out.println(hoge);
        };

とか。

エラーがある状態で(Netbeansから?)実行すると

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - 内部クラスから参照されるローカル変数は、finalまたは事実上のfinalである必要があります

とか

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - ラムダ式から参照されるローカル変数は、finalまたは事実上のfinalである必要があります

わかりやすいメッセージが表示される。

軽く触った感じだときれいに動いている。

(講演してくれた方がこのfinalまわりでよくはまったといっていたので、まだトラップありそうな気がする)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です