Javaのfinal修飾子はクラス、メソッド、変数全てにつけることができますが、
それぞれ意味が異なります。
クラスに付ける場合 [継承の禁止]
クラスにfinal修飾子を付けた場合は、そのクラスは継承することが出来なくなります。コンパイルの段階でエラーとなります。
// final修飾子のクラス
final class FinalDemo {
String name = "final付きのクラス";
public final void getInfo() {
System.out.println(this.name);
}
}
// 小クラス
class FinalDemoChild extends FinalDemo {
}
class MyApp {
public static void main(String[] args) {
FinalDemoChild demo = new FinalDemoChild();
}
}
実行結果
$ java Myapp
Error:(8, 21) java: final final_demoからは継承できません
メソッドに付ける場合 [オーバーライドの禁止]
クラスのメソッドにfinalを付けた場合、そのメソッド子クラスでのオーバーライドが不可となります。
// final付きのクラス
class FinalDemo {
String name = "final付きのクラス";
public final void getInfo() {
System.out.println(this.name);
}
}
// 小クラス
class FinalDemoChild extends FinalDemo {
@Override
public void getInfo() {
System.out.println(this.name + "の小クラス");
}
}
class MyApp {
public static void main(String[] args) {
FinalDemoChild demo = new FinalDemoChild();
}
}
実行結果
$ java MyApp
Error:(11, 17) java: FinalDemoChildのgetInfo()はFinalDemoのgetInfo()をオーバーライドできません
オーバーライドされたメソッドはfinalです
変数に付ける場合 [再代入の禁止(定数)]
変数(フィールド)にfinalを付けると再代入ができなくなります。つまり定数です。instanceで変更する必要がないのでstaticを付けてクラス変数で宣言することが多いそうです。また、他の言語と同様、定数は全て大文字で記述します。
// final付きのクラス
class FinalDemo {
public static final String NAME = "final付きの変数";
}
class MyApp {
public static void main(String[] args) {
// 定数の変更
FinalDemo.NAME = "再代入";
}
}
実行結果
$ java MyApp
Error:(9, 18) java: final変数NAMEに値を代入することはできません