Code Fix

上級

local variables must be final or effectively final の原因と直し方

ラムダが参照するローカル変数は再代入できません。配列で回避する定石も扱います。

エラーメッセージの読み方

Main.java:7: error: local variables referenced from a lambda expression must be final or effectively final
Main.java
ファイル名
7
行番号 — javacが異常に気づいた位置。原因の行とは限りません
error
種別 — コンパイルエラー。実行まで到達しません
local variables referenced from a lambda expression must be final or effectively final
内容 — javacが期待していたもの、または見つけられなかったもの

このエラーが出る典型パターン

パターン1

 1  import java.util.List;
 2  
 3  public class Main {
 4      public static void main(String[] args) {
 5          int count = 0;
 6          count = 1;        
                     ^
 7          List.of(1, 2, 3).forEach(n -> System.out.println(n + count));
 8      }
 9  }
Main.java:7: error: local variables referenced from a lambda expression must be final or effectively final

ラムダが参照するローカル変数は再代入できません。ラムダより前であっても、一度でも代入し直すと実質finalではなくなります。

直し方: count = 1;(空) にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  import java.util.List;
 2  
 3  public class Main {
 4      public static void main(String[] args) {
 5          int[] sum = {0};
 6          List.of(1, 2, 3).forEach(n -> sum = new int[]{n});
                                                   ^
 7          System.out.println(sum[0]);
 8      }
 9  }
Main.java:6: error: local variables referenced from a lambda expression must be final or effectively final

配列変数そのものは再代入していないので、要素の書き換えは許されます。実質finalの回避策として使われます。

直し方: sum = new int[]{n}sum[0] += n にします。

この問題を解いてみる →

パターン3

 1  import java.util.function.Function;
 2  
 3  public class Main {
 4      public static void main(String[] args) {
 5          Function<Integer, Integer> f = n =>  n * 2;
                                              ^
 6          System.out.println(f.apply(3));
 7      }
 8  }
Main.java:5: error: illegal start of expression

Javaのラムダの矢印は -> です。=> は他の言語の記法で、Javaでは通りません。

直し方: =>-> にします。

この問題を解いてみる →

よくある誤解

配列で回避するのは常套手段ですが、そうしたくなったら設計を疑う合図でもあります。

まとめ

local variables must be final or effectively finalは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)