Java言語のfinal変数についての注意点です。
final変数は『数値に名前を付ける』という使い方が多いのではないでしょうか。(一部言語では定数『const』と呼ばれることもあります。)
そのfinal変数ですが、使い方によっては初期化に注意が必要です。
switch文のcase式にfinal変数を使う場合、初期化は宣言と同時に行わないとエラーになってしまいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class SampleFinal{ public static void main(String[] args){ //宣言と初期化を分けた場合 final int BLUE; BLUE = 0; int color= 0; System.out.println("BLUE : " + BLUE); /* とりあえずコメントです。 switch(color){ case BLUE: System.out.println("青です。"); break; default: System.out.println("無色です。"); break; } */ } } |
ところが、コメントの部分を外すとコンパイルエラーが発生します。宣言と初期化を分けて記述すると「定数ではない」と理解されるようです。これをコンパイル・実行すると「BLUE : 0」と問題なく表示されます。
final int BLUE = 0;
というように、宣言と初期化を同時に行うと問題なくコンパイルすることができます。
final変数というのはその性質上、宣言するときにはすでに値が決まっていることが多いので、宣言と初期化は同時に行ったほうが無難といえます。
次にfinal配列の例を挙げます。
1 2 3 4 5 6 7 8 9 10 11 |
public class SampleFinalArray{ public static void main(String args[]){ final int[] FINAL_ARY = {1,2,3,4}; FINAL_ARY[0] = 10; //この行はエラーにならない for(int i = 0 ; i < FINAL_ARY.length ; i++){ System.out.println("FINAL_ARY[" + i + "] : " + FINAL_ARY[i]); } } } |
FINAL_ARYはfinalなのですが、それは参照するオブジェクトが不変なのであって、そのオブジェクトの内容まで不変であることは保証しません。
最後はfinalフィールドの場合です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class MyColor{ final int BLUE = 0; } public class SampleFinalField{ public static void main(String[] args){ int color = 0; MyColor mc = new MyColor(); switch(color){ case mc.BLUE: System.out.println("青です。"); break; default: System.out.println("無色です。"); break; } } } |
main()メソッドでMyColorクラスのインスタンスを生成し、BLUEフィールドをcase式の定数に記述しました。MyColorクラスにfinalフィールドを宣言しています。
一見問題なさそうですが、やはりコンパイルエラーになります。
final MyColor mc = new MyColor();というように、参照変数にfinalを付与しても同じくエラーになります。
Java言語で、フィールド定数として扱うには、staticであることが条件のようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class MyColor{ static final int BLUE = 0; } public class SampleFinalField{ public static void main(String[] args){ int color = 0; // MyColor mc = new MyColor(); switch(color){ case MyColor.BLUE: System.out.println("青です。"); break; default: System.out.println("無色です。"); break; } } } |
上記のように修正すると、コンパイルがとおり、実行もできるようになります。
MyColorクラスをインスタンス化しその変数から呼び出す方法ではエラーが解消されません。(上記のコメントをはずし、case mc.BLUEにする方法)finalフィールドを定数として扱うにはクラス名.フィールド名でアクセスしなければなりません。