Java | final変数(定数のように使う)

Java Java
スポンサーリンク

Javaのfinal(定数)をやさしく解説

知らないとつまずきやすいけど、わかると一気にコードが安定します。finalは「この変数、あとで変えないよ」という約束です。定数として使うための魔法の印だと思ってください。


基本:finalをつけると一度しか代入できない

  • 意味: 1回だけ値をセットできる変数。2回目以降はエラー。
  • イメージ: 「賞状に書いた名前を消して書き直せない」感じ。
  • ポイント: 宣言時に入れてもいいし、後から1回だけでもOK。
final int NUMBER = 10;
NUMBER = 20; // エラー:finalは再代入不可
Java
  • 後から1回だけ代入する例:
final int BONUS;
BONUS = 5000;   // ここで初めて代入はOK
// BONUS = 6000; // エラー:2回目は不可
Java

使う理由:バグ予防と読みやすさ

  • 安全: 変えちゃいけない値を守れる(誤代入のバグが消える)。
  • 意味が伝わる: 「これは固定の値だな」と読み手に伝わる。
  • 修正が簡単: 1か所の定数を変えるだけで全体に反映。
final float TAX_RATE = 0.1F; // 消費税率10%
float price = 800 * (1 + TAX_RATE); // 800円に税を足す
System.out.println(price);
Java

ルール:定数の名前のつけ方(慣習)

  • 大文字+アンダースコア: 定数は ALL_CAPS が基本。
  • 読みやすさ重視: 単語をつなぐときは_で区切る。
final int MAX_VALUE = 100;
final float PI = 3.1415926F;
final String DEFAULT_USER_NAME = "guest";
Java

よくあるつまずきポイント

  • 型に合う値を入れる: 例えば float に小数を入れるときは末尾に F をつける。
final float RATE = 0.05F; // Fが必要
Java
  • 参照型のfinal: 参照(オブジェクト)を指す変数をfinalにすると「別のオブジェクトを指し直せない」だけ。中身の変更は別問題。
final int[] nums = {1, 2, 3};
// nums = new int[]{4, 5}; // エラー:参照の差し替えは不可
nums[0] = 99;              // OK:配列の中身の変更は可能
Java
  • ブロック内の一度きり: 条件分岐で複数回代入しないよう注意。
final int SCORE;
if (passed) {
  SCORE = 100;
} else {
  SCORE = 60;
}
// どちらか一方で1回だけ代入されるからOK
Java

例題で理解を深める

例題1:税込価格を計算する

  • 目標: 税率を定数にして、誤って変更されないようにする。
class PriceCalc {
    public static void main(String[] args) {
        final float TAX_RATE = 0.1F; // 10%
        int base = 1200;
        float total = base * (1 + TAX_RATE);
        System.out.println("税込価格: " + total);
    }
}
Java
  • ポイント: TAX_RATE を定数にすると、別の場所で 0.12 に書き換えるミスを防げる。

例題2:ゲームの上限スコア

  • 目標: ルール上の上限を定数にして、超えないように制御。
class Game {
    public static void main(String[] args) {
        final int MAX_SCORE = 9999;
        int score = 9980;

        score += 50; // 50点加算
        if (score > MAX_SCORE) {
            score = MAX_SCORE; // 上限で止める
        }
        System.out.println("現在のスコア: " + score);
    }
}
Java
  • ポイント: ルールの「上限」を一箇所に固定して、コード全体で共有。

例題3:初期設定の不変値

  • 目標: 初期設定を一箇所で定義し、参照だけで使う。
class Settings {
    public static void main(String[] args) {
        final String APP_NAME = "MyApp";
        final int DEFAULT_TIMEOUT_SEC = 30;

        System.out.println(APP_NAME + " を起動します");
        System.out.println("タイムアウト: " + DEFAULT_TIMEOUT_SEC + "秒");
    }
}
Java
  • ポイント: 文言や数字を直書きしないことで、変更時の見落としを防げる。

一歩進む:クラス全体で使う定数(static final)

  • 目的: どのメソッドからも使える「アプリ全体の定数」を作る。
  • 書き方: static final 型 名 = 値;(「クラスに属する定数」)
class Config {
    public static final String VERSION = "1.0.3";
    public static final int PORT = 8080;
}

class Main {
    public static void main(String[] args) {
        System.out.println("Version: " + Config.VERSION);
        System.out.println("Port: " + Config.PORT);
    }
}
Java
  • ポイント: Config.VERSION のようにクラス名から参照。どこでも同じ値を共有できる。

練習問題

  1. 定数化練習: 商品価格 1500 円、割引率 20% を使って、割引後の税込価格を計算するプログラムを書いてください。
    • ヒント: final float DISCOUNT = 0.2F;final float TAX = 0.1F;
  2. 上限チェック: 体力 hp に回復値 35 を足す。最大値 100 を超えないように調整してください。
    • ヒント: final int MAX_HP = 100;
  3. 設定の集中管理: アプリ名、最大同時接続数、タイムアウト秒の3つを static finalAppConfig クラスにまとめ、Main から表示してください。

模範解答と説明

練習問題1:割引後の税込価格を計算

問題: 商品価格 1500 円、割引率 20%、消費税率 10% を使って、割引後の税込価格を計算する。

模範解答

class DiscountPrice {
    public static void main(String[] args) {
        final int BASE_PRICE = 1500;     // 元の価格
        final float DISCOUNT = 0.2F;     // 割引率20%
        final float TAX = 0.1F;          // 消費税率10%

        // 割引後の価格
        float discounted = BASE_PRICE * (1 - DISCOUNT);

        // 税込み価格
        float total = discounted * (1 + TAX);

        System.out.println("割引後の税込価格: " + total + "円");
    }
}
Java

解説

  • final を使って 変わらない値(価格・割引率・税率) を定数化。
  • BASE_PRICE * (1 - DISCOUNT) で割引後の価格を計算。
  • さらに (1 + TAX) を掛けて税込価格を求める。
  • 定数を使うことで「0.2」や「0.1」といった数字の意味が明確になる。

練習問題2:体力の上限チェック

問題: 体力 hp に回復値 35 を足す。最大値 100 を超えないように調整する。

模範解答

class HPCheck {
    public static void main(String[] args) {
        final int MAX_HP = 100;  // 体力の上限
        int hp = 80;             // 現在の体力
        int heal = 35;           // 回復量

        hp += heal;              // 回復を加算

        if (hp > MAX_HP) {
            hp = MAX_HP;         // 上限を超えたら調整
        }

        System.out.println("現在のHP: " + hp);
    }
}
Java

解説

  • MAX_HP を定数にすることで「100」という数字の意味が明確に。
  • if (hp > MAX_HP) で上限を超えたかチェック。
  • 超えていたら hp = MAX_HP; にして調整。
  • こうすることで「HPが100を超える」という不自然な状態を防げる。

練習問題3:設定の集中管理

問題: アプリ名、最大同時接続数、タイムアウト秒を static finalAppConfig クラスにまとめ、Main から表示する。

模範解答

class AppConfig {
    public static final String APP_NAME = "MyCoolApp"; // アプリ名
    public static final int MAX_CONNECTIONS = 50;      // 最大同時接続数
    public static final int TIMEOUT_SEC = 30;          // タイムアウト秒
}

class Main {
    public static void main(String[] args) {
        System.out.println("アプリ名: " + AppConfig.APP_NAME);
        System.out.println("最大接続数: " + AppConfig.MAX_CONNECTIONS);
        System.out.println("タイムアウト: " + AppConfig.TIMEOUT_SEC + "秒");
    }
}
Java

解説

  • static final を使うと「クラスに属する定数」になる。
  • AppConfig.APP_NAME のように クラス名.定数名 で呼び出せる。
  • アプリ全体で共通の設定値を一箇所にまとめられるので、管理が楽になる。

まとめ

  • final → 一度だけ代入できる変数(定数)
  • static final → クラス全体で共有できる定数
  • 定数を使うと「意味が明確」「修正が簡単」「バグ防止」に役立つ
タイトルとURLをコピーしました