Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaでfinalキーワードを使わずに一度だけ値を設定できる変数を作成する方法

Javaでは、finalキーワードを付けた変数は一度初期化すると二度と値を変更できません。つまり、final変数に値を代入できるのは1回だけです。final変数に対して再度値を代入しようとすると、コンパイル時エラーが発生します。

final変数の基本的な挙動

まず、通常のfinal変数がどのように動作するのか、次のサンプルコードで確認してみましょう。

サンプルコード

public class FinalExample {
    final int j = 100;
    public static void main(String args[]){
        FinalExample obj = new FinalExample();
        obj.j = 500;
        System.out.println(obj.j);
    }
}

コンパイル時エラー

FinalExample.java:6: error: cannot assign a value to final variable j
    obj.j = 500;
       ^
1 error

このように、final変数への2回目の代入はコンパイラによって拒否され、プログラムはビルドできません。

finalキーワードを使わずに「final」と同等の機能を実現する

ここからが本題です。finalキーワードを実際には使用せずに、「一度だけ設定できる変数」としての振る舞いを実現するには、次のアプローチが有効です。

  • 変数をprivateにする:外部から直接アクセスできないようカプセル化します。
  • setterメソッド経由でのみ値を設定する:setter内で、すでに値が設定済みの場合は前回の値をそのまま保持するか、例外をスローするように制御します。

実装例

public class FinalExample {
    // 2回目以降の代入を無視するパターン
    private Integer num;
    public void setNum(int num){
        this.num = this.num == null ? num : this.num;
    }

    // 2回目の代入で例外をスローするパターン
    private String data;
    public void setData(String data) {
        this.data = this.data == null ? data : demo();
    }
    public String demo() {
        String msg = "data変数に2回目の値を設定することはできません";
        throw new RuntimeException(msg);
    }

    public static void main(String args[]){
        FinalExample obj = new FinalExample();
        obj.setNum(200);
        System.out.println(obj.num);
        obj.setNum(500);
        System.out.println(obj.num);
        obj.setData("hello");
        obj.setData("sample data");
    }
}

実行結果

200
200
Exception in thread "main" java.lang.RuntimeException: data変数に2回目の値を設定することはできません
at SEPTEMBER.remaining.FinalExample.demo(FinalExample.java:15)
at SEPTEMBER.remaining.FinalExample.setData(FinalExample.java:12)
at SEPTEMBER.remaining.FinalExample.main(FinalExample.java:26)

この例では、numフィールドへの2回目の代入(500)は黙って無視され、最初に設定した200が出力されています。一方、dataフィールドへの2回目の代入では、RuntimeExceptionがスローされてプログラムが異常終了します。

実装のポイント

  • nullチェックによる初回判定:フィールドがnullかどうかを確認することで、その代入が初回かどうかを判別できます。
  • 三項演算子による分岐this.num == null ? num : this.num のように、初回のみ引数の値を採用し、それ以降は既存の値を維持することで、事実上の「書き換え不可」を実現しています。
  • 例外による厳格な制御:不正な代入を黙って無視するのではなく例外をスローすることで、呼び出し側のミスを明示できます。バグの早期発見につながるため、実務では例外を投げる方式が推奨されます。

注意点

この手法はあくまで実行時の制御であるため、finalキーワードのようなコンパイラによる静的なチェックは受けられません。また、リフレクションなどを使えば外部から強制的に書き換えられる可能性もあります。特別な理由がない限り、本来のfinalキーワードを使用するのが最も安全で確実です。この手法は、フレームワークの制約や設計上の都合でfinal化できない場合の代替策として活用するとよいでしょう。

  1. JavaでJTextFieldに数値のみ入力できるようにする方法

    JTextFieldの入力制限とはデフォルトのJTextFieldは、数値・文字・特殊文字など、あらゆる種類の入力を受け付けることができます。しかし、ユーザーがJTextFieldに入力した内容を検証するのは意外と難しく、特にintなどの数値型へ変換する必要がある場合は注意が必要です。本記事では、JTextFieldに数値のみ入力できるように制限する方法を、具体的なサンプルコードとともに解説します。実装のポイントキー入力を監視するためにKeyListener(KeyAdapter)を使用し、押されたキーの文字が「0」から「9」の範囲内であるかどうかを判定します。数値であれば編集を許可し、それ以

  2. Javaでログインフォームを作成する方法!Swingを使った実装例とサンプルコード

    JavaではSwingというGUIツールキットを利用することで、デスクトップアプリケーション向けのログインフォームを簡単に開発できます。この記事では、ユーザー名(User Name)とパスワード(Password)の2つのラベル、認証情報を入力するための2つのテキストフィールド、そしてSUBMIT(送信)ボタンを1つ備えたフォームを作成します。正しい認証情報が入力されると、フォーム上に「Hello admin」というメッセージが表示されます。 使用する主なコンポーネント JLabel:ラベルの表示に使用します。 JTextField:ユーザー名の入力欄です。 JPasswordField: