先日の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までだと下みたいにエラー。
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まわりでよくはまったといっていたので、まだトラップありそうな気がする)