final
このページではfinal修飾子について説明します。
概要
final修飾子はクラス、メソッド、変数の宣言時に付与することができます。以下ではそれぞれのケースにおいてfinal修飾子の説明をします。
クラス宣言時にfinalを使用
final修飾子を付与してクラスを宣言するとそのクラスはサブクラスで継承できなくなります。finalを使用する理由の一つとしてセキュリティ上の問題があります。プログラムに不正動作を与えようとするハッカーたちの一つの手段としてあるクラスのサブクラスを作成し、そのサブクラスに不正な動作を行う処理を記述すると言うのがあります。サブクラスを作成することにより、スーパークラスで想定される動作とはまったく異なる動作を行わせるものです。
また、セキュリティ上の観点だけからでなく、技術力のあまりない人がサブクラスを作成し、予期せぬ動作をするプログラムが作成されることを防ぐためにも使用します。Javaで初めから用意されているStringクラスや、Mathクラスはfinalが付与され宣言されており、サブクラスが作成されないようにしています。
【例1】クラス宣言時にfinalを指定した例
final class ExClass15 {
//スーパークラスExClass15
}
class subExClass15 extends ExClass15 {
//スーパークラスExClass15をサブクラスsubExClass15で継承
//ExClass15はfinalが付与されているため継承できない、コンパイルエラー
}
メソッド宣言時にfinalを使用
final修飾子を付与してメソッドを宣言するとそのメソッドはサブクラスでオーバーライドできなくなります。クラス全体を継承できなくすると都合が悪い場合に使用します。
【例2】メソッド宣言時にfinalを指定した例
class ExClass16 {
final void show() {
//スーパークラスのshowメソッド
}
}
class subExClass16 extends ExClass16 {
void show() {
//スーパークラスのshowメソッドをオーバーライド
//finalが付与されているためオーバーライドできない、コンパイルエラー
}
}
変数宣言時にfinalを使用
final修飾子を付与して変数を宣言するとその変数は定数として扱われます。finalが付与された変数に一度値を代入するとその値を変更することはできません。(Javaの道:変数(final変数))
finalをint、doubleなどの基本型(プリミティブ型)の変数に利用した場合は特に問題はありませんが、参照型の変数に利用した場合は注意点があります。参照型変数の参照情報を変更することはできませんが、参照型変数を通してその変数自体の値は変更できると言う点です。参照情報の詳細については、「Javaの道:インスタンス」を参照してください。
参照型変数にfinalを使用した例を以下に記載します。
ExClass17クラス
class ExClass17 {
int value;
//コンストラクタ、メンバ変数valueを初期化
ExClass17(int value) {
this.value = value;
}
}
Mainクラス
class Main {
public static void main(String[ ] args) {
//finalを指定し、参照型変数ins1を宣言
final ExClass17 ins1 = new ExClass17(100);
//finalを指定しているため、変数ins1の参照情報は変更不可、コンパイルエラー
//ins1 = new ExClass17(200);
//参照情報を変えず、値の変更は可
ins1.value = 200;
System.out.println("valueの値は" + ins1.value);
}
}
13final