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のようにクラス名から参照。どこでも同じ値を共有できる。
練習問題
- 定数化練習: 商品価格 1500 円、割引率 20% を使って、割引後の税込価格を計算するプログラムを書いてください。
- ヒント:
final float DISCOUNT = 0.2F;とfinal float TAX = 0.1F;
- ヒント:
- 上限チェック: 体力
hpに回復値 35 を足す。最大値 100 を超えないように調整してください。- ヒント:
final int MAX_HP = 100;
- ヒント:
- 設定の集中管理: アプリ名、最大同時接続数、タイムアウト秒の3つを
static finalでAppConfigクラスにまとめ、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 final で AppConfig クラスにまとめ、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→ クラス全体で共有できる定数- 定数を使うと「意味が明確」「修正が簡単」「バグ防止」に役立つ
