cannot assign a value to final variable の原因と直し方
finalが固定するのは参照であって中身ではありません。final / static final の違いを整理します。
エラーメッセージの読み方
Main.java:4: error: cannot assign a value to final variable LIMIT
Main.java- ファイル名
4- 行番号 — javacが異常に気づいた位置。原因の行とは限りません
error- 種別 — コンパイルエラー。実行まで到達しません
cannot assign a value to final variable LIMIT- 内容 — javacが期待していたもの、または見つけられなかったもの
このエラーが出る典型パターン
パターン1
1 public class Main { 2 public static void main(String[] args) { 3 final int LIMIT = 10; 4 LIMIT = 20; ^ 5 System.out.println(LIMIT); 6 } 7 }
Main.java:4: error: cannot assign a value to final variable LIMIT
finalは1度しか代入できません。定数として使うなら宣言と同時に初期化し、以後は再代入しません。
直し方: LIMIT = 20; を (空) にします。
広告
広告スロット(未設定)
パターン2
1 import java.util.ArrayList; 2 import java.util.List; 3 4 public class Main { 5 public static void main(String[] args) { 6 final List<String> list = new ArrayList<>(); 7 list = new ArrayList<>(); ^ 8 System.out.println(list); 9 } 10 }
Main.java:7: error: cannot assign a value to final variable list
finalが固定するのは参照であって中身ではありません。要素の追加や削除は自由にできます。
直し方: list = new ArrayList<>() を list.add("a") にします。
パターン3
1 public class Main { 2 static final int ID; ^ 3 Main(int id) { this.ID = id; } 4 public static void main(String[] args) { 5 System.out.println(new Main(7).ID); 6 } 7 }
Main.java:3: error: cannot assign a value to final variable ID
static finalはクラス単位の定数なのでコンストラクタで代入できません。インスタンスごとに固定するならfinalのみです。
直し方: static final を final にします。
よくある誤解
finalなListの中身は変えられます。本当に不変にしたいなら List.of を使ってください。
まとめ
cannot assign a value to final variableは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。