スライドショー

【Java入門】static final修飾子でクラス定数を使う方法まとめ

Javaには変数の値を自由に変更できないように「static final」を使用することがあります。

この記事では、static finalの、

  • final修飾子の意味
  • final修飾子の基本的な使い方
  • クラスにfinalを指定する方法
  • メソッドにfinalを指定する方法
  • クラス定数の初期化
  • 配列にfinalを指定する方法
  • ListやMapにfinalを指定する方法

という基本的な内容から、などの応用的な使い方に関しても解説していきます。

今回はそんなstatic finalの処理について、さまざまな方法をわかりやすく解説します!

final修飾子とは

変数は基本的に値を自由に変更できますが、一度値を設定したら変更されない変数のことを「定数」と呼びます。final修飾子を指定した変数は、基本的に規定値など一度値を設定したら変更する必要がない値に用いられます。

以下はfinal修飾子を指定して、クラス定数を宣言しています。クラス定数を指定する場合は、変数の宣言の頭にstatic finalを記述します。

public static final double DNUM = 3.1415926535

final修飾子は変数以外にもメソッドやクラスにも指定することができます。

変数、メソッド、クラスにfinal修飾子を指定した場合は以下のようになります。

  • クラスにfinalを指定した場合は、そのクラスを継承することはできません。
  • メソッドにfinalを指定した場合は、そのメソッドをオーバーライドすることはできません。
  • 変数にfinalを指定した場合は、その変数の値を変更することはできません。

また、final修飾子を指定した定数は、通常の変数と区別するために変数名の英数字を大文字で記述することが多いです。

final修飾子の基本的な使い方

以下にfinal修飾子を使用した基本的な使い方を記述します。

public class Main {
    
    //static finalを使用してクラス定数を宣言する
    public static final double DNUM = 3.1415926535;

    public static void main(String[] args) throws Exception {

        System.out.println("DNUM : " + DNUM);

    }
}
実行結果
DNUM : 3.1415926535

サンプルでは、クラスの直下にstatic finalでdouble型のクラス定数を宣言しています。mainメソッドで、クラス定数の値が正しく設定されていることを確認できます。

また、定数は先述したとおり一度値を設定したら再度設定することはできませんのでメソッド内で以下のように定数を設定してもコンパイルエラーとなります。

DNUM  = 100.0;

クラスにfinalを指定する方法

以下にfinal修飾子をクラスに指定した場合のサンプルを記述します。

前述したとおり、クラスにfinal修飾子を指定すると、そのクラスは継承できなくなります。

final public class ParentClass {

    public static void main(String[] args) {
		
        System.out.println("ParentClass");
		
        //クラスのオブジェクトを生成
        SubClass sb = new SubClass();
        sb.subMethod();
    }
}
public class SubClass extends ParentClass{
	
    public void subMethod(){
		
        System.out.println("SubClass");
		
    }
}

このサンプルでは親クラスにあたるParentClassをfinal修飾子で指定しているため、その子クラスであるSubClassで、extendsによる親クラスの継承を指定しても、以下のエラーとなります。

型 SubClass は final クラス ParentClass をサブクラス化できません

メソッドにfinalを指定する方法

以下にfinal修飾子をメソッドに指定した場合のサンプルを記述します。前述したとおりメソッドにfinal修飾子を指定すると、そのメソッドはオーバライドできなくなります。

public class ParentClass {

    final public void ParentMethod(){

        System.out.println("ParentMeshotd");
    }
}
public class SubClass extends ParentClass{
		
    public void ParentMethod(){

        System.out.println("parentMethod");
    }
}

このサンプルでは親クラスにあたるParentClassのメソッドをfinal修飾子で指定しているため、その子クラスであるSubClassで、親クラスのメソッドを指定しても、以下のエラーとなります。

ParentClass からの final メソッドをオーバーライドできません

クラス定数の初期化

定数は基本的に宣言時に値を設定し、一度値を代入したら再設定はできません。そのため、宣言時に値を設定しなかった場合、メソッド内で初めて値を設定しようとしてもコンパイルエラーが発生します。

定数の数が多く、宣言と初期化処理を分けたい場合は、staticイニシャライザ内なら定数を初期化することが可能です。以下に定数の宣言と、定数の初期化処理を分けて記載するためのサンプルを記述します。

public class Main {
    
    public static final int NUM1;
    public static final int NUM2;

    //static内で定数の初期化
    static {
        NUM1 = 10;
        NUM2 = 20;
    }

    public static void main(String[] args) throws Exception {

        System.out.println("NUM1 : " + NUM1);
        System.out.println("NUM2: " + NUM2);

    }
}
実行結果
NUM1 : 10
NUM2 : 20

配列にfinalを指定する方法

final修飾子は、配列にも指定することができます。しかし、配列をfinalで宣言しても変更できないのは配列のインスタンスであり、配列の要素を変更することは可能です。

public class ParentClass {
	
    //配列のfinal修飾子を指定する
    public static final int[] FOO = {0, 1, 2, 3};

    public static void main(String[] args) {

        //finalを指定しても配列の要素は変更できる。
        FOO[0] = 10;

        System.out.println(FOO[0]);

    }
}
実行結果
10

実行結果からわかるように、final修飾子で配列を宣言しても要素自体は変更できてしまいます。そのため、保持している要素を変えられたくない場合は、ListやMapなどの動的配列を使用する方法があります。

ListやMapをfinal修飾子を指定した定数として扱う方法は、次項で詳しく解説します。

ListやMapにfinalを指定する方法

定数は基本的に一度値を設定したら変更できませんが、ListやMapなどの動的配列をstatic finalで指定しても、値の変更ができてしまいます。

もし、ListやMapなどをfinal修飾子を指定した定数として扱いたいのなら、CollectionsクラスのunmodifiableListメソッドを使用する方法があります。

unmodifiableListメソッドは、ListやMapを読み取り専用とする機能で、設定したListやMapに値の変更や追加などを実施すると、UnsupportedOperationExceptionの例外が発生します。

そのため、unmodifiableListメソッドを使用すれば、定数として使用できることが可能となります。

以下にunmodifiableListメソッドを使用した、定数化の方法を記述します。

public class Main {

    //unmodifiableListを使用して定数を宣言する
    public static final List<String> LIST_MOD = 
        Collections.unmodifiableList(new ArrayList<String>() 
        {{ add("apple"); add("orange"); add("melon"); }} );

    public static void main(String[] args) throws Exception {

        System.out.println(LIST_MOD.get(0));
        System.out.println(LIST_MOD.get(1));
        System.out.println(LIST_MOD.get(2));

    }
}
実行結果
apple
orange
melon

finalについてもっと詳しく知りたい方へ

この記事で解説したようにfinal修飾子を指定すれば、その変数やクラス、メソッドの内容を自由に変更することができなくなります。そのため、不用意に値やクラス、メソッドの内容を変えられたくない場合はfinal修飾子を指定するのが望ましいと言えます。

finalのさまざまな使い方については、以下の記事にまとめていますので、「final修飾子についてもっと知りたい!」という方はぜひ参考にしてくださいね!

static修飾子の使い方について

この記事で紹介したstatic修飾子は。主にクラスをインスタンス化せずに、直接メソッドや変数にアクセスできる便利な修飾子です。そんなstatic修飾子を活用する方法については、以下の記事で詳細に解説していますので、気になった方はぜひ参考にしてください!

【Java入門】static修飾子の使い方総まとめ
更新日 : 2017年6月9日

まとめ

ここでは、static finalの意味や基本的な使い方、初期化の方法やList、Mapの定数化などを説明しました。

final修飾子は、変更する予定のない規定値などを設定する場合に、変数と区別するために定数としてよく使用されます。もしstatic finalの記述方法を忘れてしまったら、この記事を思い出してくださいね!

LINEで送る
Pocket

無料でSEからWebエンジニアへ転職しませんか?



侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、

  • システムエンジニアという職業だけどコードが書けない
  • 事務作業が多くスキルがないため将来が不安
  • スクールに通うと完全未経験者と同じスタートになるからレベルが合わない
という、すでに知識があるSEならではのお悩みがあることに気づきました。そんな方におすすめなのが、弊社の「転職コース 」です。

弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。さらにこちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。

既に知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。

まずは無料体験レッスンを予約する

書いた人

侍ブログ編集部

侍ブログ編集部

侍エンジニア塾は「人生を変えるプログラミング学習」をコンセンプトに、過去多くのフリーランスエンジニアを輩出したプログラミングスクールです。プログラミングに役立つ情報や有用な情報を発信していきます。
サービスページはこちら
ツイッターはこちら
フェイスブックはこちら

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説