
Java道|finalの使い方と役割
自由に広げるだけが、よい設計ではありません。
final を使うと、変えてはいけない技、広げてはいけない型、書き換えてはいけない値を、Javaのコードにはっきり刻めます。
これまで、Javaのオブジェクト指向では、継承によってクラスを広げたり、オーバーライドによって親クラスのメソッドを子クラス向けに作り直したりできることを見てきました。
継承やオーバーライドは、とても便利です。
親クラスに共通部分をまとめ、子クラスで個性を加えられるからです。
鬼滅の刃風にたとえると、鬼殺隊士という共通の土台があり、そこから柱のような特別な隊士を作るイメージです。
さらに、柱ごとに戦い方や表示の仕方を変えたい場合は、オーバーライドで自分流に作り直せます。
ただし、設計では「自由に変えられること」だけが正解ではありません。
中には、次のようなものもあります。
| 守りたいもの | 例 |
|---|---|
| 子クラスで勝手に変えてほしくない処理 | 隊士認証の手順 |
| これ以上継承させたくない完成済みのクラス | 最終奥義を持つ完成形の隊士クラス |
| 書き換えられてはいけない値 | 最大隊士数、任務規則、固定された基準値 |
このような「ここは変えないでほしい」という設計上の意図を表すために使うのが final です。
final は、単に厳しく制限するためのものではありません。
変えてよい場所と、変えてはいけない場所をはっきり分けるための修飾子 です。
final は「それ以上変更させない」を表す
final の基本イメージは、とてもシンプルです。
それ以上変更させない
これが final の中心にある意味です。
ただし、final をどこに付けるかによって、何を変更できなくするのかが変わります。
| final を付ける場所 | 変更できなくなるもの | 意味 |
|---|---|---|
| メソッド | オーバーライド | 子クラスで上書きできない |
| クラス | 継承 | サブクラスを作れない |
| フィールド | 値の再代入 | 値を変更できない |
鬼滅の刃風にたとえると、次のように考えると分かりやすいです。
| final の対象 | 鬼滅の刃風のイメージ |
|---|---|
| final メソッド | この技の型は変えてはいけない |
| final クラス | この隊士の型は完成形なので派生させない |
| final フィールド | この数値は隊の絶対ルールなので書き換えない |
同じ final でも、付ける場所によって役割が変わります。
そのため、final を見たときは、まず「何を固定しているのか」を確認することが大切です。
↓クリックすると拡大表示されます。

メソッドに final を付ける意味
まずは、メソッドに付ける final です。
メソッドに final を付けると、そのメソッドはサブクラスでオーバーライドできなくなります。
たとえば、DemonSlayer クラスに showRule() というメソッドがあるとします。
class DemonSlayer
{
public final void showRule()
{
System.out.println("鬼殺隊士は任務規則を守ります。");
}
}このように public final void showRule() と書くと、サブクラスで同じ showRule() を定義して上書きすることはできません。
class PillarSlayer extends DemonSlayer
{
// これはできない
public void showRule()
{
System.out.println("柱専用の規則に変えます。");
}
}このように書こうとすると、エラーになります。
なぜなら、親クラス側で final を付けているため、showRule() は「子クラスで変更してはいけないメソッド」として固定されているからです。
なぜメソッドをオーバーライド禁止にするのか
オーバーライドは便利です。
子クラスごとにふさわしい動きへ作り直せるからです。
しかし、すべてのメソッドを自由にオーバーライドできると困る場合があります。
たとえば、次のような処理です。
| 変えられると困る処理 | 理由 |
|---|---|
| 認証処理 | 勝手に変えられると安全性が崩れる |
| 共通ルール表示 | 子クラスごとに違う内容になると統一性がなくなる |
| 重要な手順 | 処理順序が変わると不具合の原因になる |
| 基本契約の処理 | クラス全体の意味が崩れる |
鬼滅の刃風にたとえると、鬼殺隊士には全員が守るべき共通の任務規則があります。
たとえば、
| 共通規則 | 内容 |
|---|---|
| 身元確認 | 隊士であることを確認する |
| 任務確認 | 担当任務を確認する |
| 規則遵守 | 鬼殺隊の決まりを守る |
このような処理を子クラス側で勝手に変えられると、隊全体のルールが崩れてしまいます。
そのため、親クラスのメソッドに final を付けて、
この振る舞いは共通ルールとして固定します
と宣言します。
メソッド final の見方
メソッドに final が付いているときは、次のように読み取ります。
| 書き方 | 読み取り方 |
|---|---|
| public final void showRule() | このメソッドは子クラスでオーバーライドできない |
| final がないメソッド | 条件を満たせばオーバーライドできる |
つまり、メソッド final は、子クラスの自由をすべて否定するものではありません。
変えてよいメソッドと、変えてはいけないメソッドを分けるための指定 です。
| メソッドの種類 | final を付けるか |
|---|---|
| 子クラスごとに動きを変えてよいもの | 付けない |
| 全クラスで同じ動きを守らせたいもの | 付ける |
鬼滅の刃風にたとえると、隊士ごとの呼吸の型は変えてよくても、隊の絶対規則は変えてはいけない、ということです。
クラスに final を付ける意味
次に、クラスに付ける final です。
クラスに final を付けると、そのクラスは継承できなくなります。
つまり、そのクラスを親クラスにしてサブクラスを作ることができません。
たとえば、次のように書きます。
final class FinalBreathingStyle
{
public void showStyle()
{
System.out.println("完成された呼吸の型です。");
}
}この FinalBreathingStyle クラスは final class なので、次のように継承できません。
// これはできない
class CustomBreathingStyle extends FinalBreathingStyle
{
}final class は、
このクラスはここで完成形なので、これ以上派生させません
という意味を持ちます。
なぜクラスを継承禁止にするのか
継承は強力です。
既存のクラスを土台にして、新しいクラスを作れるからです。
しかし、すべてのクラスを自由に継承できるようにしておくと、設計が崩れることがあります。
たとえば、次のようなクラスです。
| 継承させたくないクラス | 理由 |
|---|---|
| 完成済みのクラス | これ以上機能を変えられたくない |
| 内部ルールが厳密なクラス | 派生によって安全性が崩れる可能性がある |
| 使い方を固定したいクラス | 想定外のサブクラスを防ぎたい |
| 不変性を守りたいクラス | 子クラスで状態管理を変えられたくない |
鬼滅の刃風にたとえると、ある呼吸の最終奥義が「これ以上変化させてはいけない完成形」として定められているようなものです。
もし、その型を自由に派生できるようにしてしまうと、元の意味やルールが崩れるかもしれません。
そのため、クラスに final を付けて、
この型はここで完成です
これ以上、派生形は作らせません
と宣言します。
クラス final の役割を整理する
クラスに final を付ける場面を整理すると、次のようになります。
| こんなとき | final を付ける意味 |
|---|---|
| そのクラスを完成形として扱いたい | 継承を禁止する |
| 派生されると設計が崩れる | サブクラス作成を防ぐ |
| 使い方を厳密に固定したい | 型の広がりを止める |
| 想定外のオーバーライドを防ぎたい | 子クラスを作らせない |
継承は拡張性を生みます。
一方で、final class は拡張性よりも安定性を優先します。
| 考え方 | 意味 |
|---|---|
| 継承を許す | 将来の拡張を考える |
| final class にする | 完成形として固定する |
鬼滅の刃風にたとえると、まだ成長や派生を許す隊士の型もあれば、完成された奥義として固定する型もある、ということです。
フィールドに final を付ける意味
最後に、フィールドに付ける final です。
フィールドに final を付けると、その値は一度設定したあと変更できなくなります。
これは、途中で書き換えてはいけない値を表すときに使います。
たとえば、鬼殺隊の最大柱数を固定したい場合、次のように書けます。
static final int MAX_PILLAR_COUNT = 9;この MAX_PILLAR_COUNT は final なので、あとから別の値を代入できません。
// これはできない
MAX_PILLAR_COUNT = 10;final フィールドは、この値は固定です という意味をコードに表します。
フィールド final はなぜ大切か
プログラムの中には、変わってよい値と、変わってはいけない値があります。
鬼滅の刃風にたとえると、隊士の現在地や体力は状況によって変わります。
しかし、鬼殺隊の基本規則や最大柱数のような値は、勝手に変わってはいけません。
| 値の種類 | 変わるか |
|---|---|
| 隊士の現在地 | 変わる |
| 隊士の体力 | 変わる |
| 任務中の状態 | 変わる |
| 最大柱数 | 変わらない |
| 基本規則の番号 | 変わらない |
もし、変わってはいけない値が途中で書き換えられると、次のような問題が起こります。
| 問題 | 内容 |
|---|---|
| 前提が崩れる | ルールが途中で変わってしまう |
| 処理結果が不安定になる | 同じ処理でも結果が変わる可能性がある |
| バグの原因になる | どこで値が変わったのか追いにくい |
| 設計意図が伝わりにくい | 固定値なのか状態値なのか分からない |
final を付けておけば、この値は変更しないものだと明確になります。
フィールド final は定数につながる
final フィールドは、定数としてよく使われます。
特に、次の形はよく出てきます。
static final int MAX_PILLAR_COUNT = 9;ここでは static と final を組み合わせています。
| 修飾子 | 役割 |
|---|---|
| static | クラス全体で共有する |
| final | 値を変更できなくする |
つまり static final は、
クラス全体で共通して使う、変更できない値
を表します。
鬼滅の刃風にたとえると、特定の隊士だけが持つ値ではなく、鬼殺隊全体で共有する決まりの数です。
たとえば、次のような定数が考えられます。
static final int MAX_PILLAR_COUNT = 9;
static final int DEFAULT_MISSION_LEVEL = 1;
static final String ORGANIZATION_NAME = "鬼殺隊";このような値は、宣言時に初期化しておくのが基本です。
final はあとから値を変えられないため、最初に何の値にするかを決めておく必要があります。
final とオーバーライドの関係
final は、オーバーライドと深く関係します。
オーバーライドは、親クラスのメソッドを子クラスで自分向けに作り直す仕組みでした。
これはとても便利です。
しかし、すべてのメソッドを自由に作り直せると、親クラスが守りたい共通ルールまで変えられてしまう可能性があります。
そこで、設計では次のように使い分けます。
| メソッドの種類 | どうするか |
|---|---|
| 子クラスごとに変えてよいもの | 通常どおりオーバーライド可能にする |
| 親クラスのルールとして固定したいもの | final を付ける |
鬼滅の刃風にたとえると、隊士ごとの戦い方は違ってよいです。
水の呼吸、炎の呼吸、風の呼吸のように、隊士ごとに個性があります。
一方で、隊士認証や任務規則の確認のような処理は、勝手に変えられると困ります。
つまり final は、
オーバーライドを否定するものではなく、オーバーライドを許す場所と許さない場所を分けるための道具
です。
final と継承の関係
クラスに final を付けると、継承できなくなります。
これは、継承が悪いからではありません。
継承させないこと自体が、設計として正しい場合があるからです。
継承を許すと、次のようなメリットがあります。
| 継承を許すメリット | 内容 |
|---|---|
| クラスを拡張できる | 新しいサブクラスを作れる |
| 共通部分を再利用できる | 親クラスの機能を使える |
| 多態性につなげられる | スーパークラス型でまとめて扱える |
一方で、継承を許すと次のようなリスクもあります。
| 継承を許すリスク | 内容 |
|---|---|
| 想定外のサブクラスが作られる | 設計者が想定していない使い方をされる |
| ルールが崩れる | 子クラスで不自然な実装がされる可能性がある |
| 管理が複雑になる | 派生クラスが増えすぎる |
| 一貫性が失われる | クラス本来の意味が薄れる |
final class は、この広がりを意図的に止めるための仕組みです。
鬼滅の刃風にたとえると、
この呼吸の型は完成形なので、これ以上派生させない
と決めるようなものです。
final と値の制御の関係
フィールドに final を付けると、値を変更できなくなります。
これは、オブジェクト指向における状態管理とも関係します。
クラスのフィールドには、状態を表すものがあります。
その中には、変わるべき値と、変わってはいけない値があります。
鬼滅の刃風に考えると、次のようになります。
| フィールド | 変わるか | 理由 |
|---|---|---|
| hp | 変わる | 戦闘で増減する |
| currentArea | 変わる | 任務で移動する |
| rank | 変わる場合がある | 昇格する可能性がある |
| MAX_PILLAR_COUNT | 変わらない | 鬼殺隊の決まりとして固定 |
| ORGANIZATION_NAME | 変わらない | 組織名として固定 |
このように、変わってよいものと、変わってはいけないものを分けると、コードの意味がはっきりします。
final フィールドは、
この値は状態ではなくルールです
と伝えるための表現でもあります。
final をどう読み取ればよいか
final が出てきたら、まず「何が止められているのか」を見ます。
| final の対象 | 止めているもの | 読み取り方 |
|---|---|---|
| メソッド | オーバーライド | この振る舞いは固定 |
| クラス | 継承 | この型は完成形 |
| フィールド | 値の変更 | この値は固定 |
たとえば、次のコードを見たとします。
public final void confirmRule()これは、confirmRule() が子クラスでオーバーライドできないという意味です。
次のコードならどうでしょうか。
final class FinalBreathingStyleこれは、FinalBreathingStyle を継承できないという意味です。
次のコードなら、値が変更できません。
static final int MAX_PILLAR_COUNT = 9;このように、final は1つの単語ですが、見る場所によって意味が変わります。
Math クラスのような final の活用イメージ
final の考え方は、数学やルールを扱うクラスを考えると理解しやすくなります。
たとえば、計算ルールを扱うクラスでは、勝手に継承されて動きを変えられると困ることがあります。
また、円周率のような値は途中で書き換えられてはいけません。
こうした場面では、final の考え方がとても自然です。
鬼滅の刃風にたとえると、これは個々の隊士が勝手に変えてよい技ではなく、世界の法則や鬼殺隊全体の規則に近いものです。
| 固定したいもの | final の使い方 |
|---|---|
| 勝手に変えてほしくない計算処理 | final メソッド |
| 継承させたくない計算クラス | final クラス |
| 書き換えてはいけない値 | final フィールド |
final は、柔軟性を減らすためだけに使うものではありません。
変えてはいけないものを明確に守るために使う と考えると、役割が分かりやすくなります。
図:final の3つの使い方
↓クリックすると拡大表示されます。

この図が示していること
この図では、final の3つの使い方を並べて整理しています。
左側は final メソッドです。
メソッドに final を付けると、子クラスでオーバーライドできなくなります。
中央は final クラスです。
クラスに final を付けると、そのクラスを継承できなくなります。
右側は final フィールドです。
フィールドに final を付けると、その値を変更できなくなります。
この図から分かることは、final の共通イメージは「それ以上変更させない」ですが、何を止めるのかは付ける場所によって変わるということです。
図:final と継承・オーバーライドの境界線
↓クリックすると拡大表示されます。

この図が示していること
この図では、final が継承やオーバーライドの中でどのように境界線を作るかを表しています。
DemonSlayer クラスには、attack() と final showRule() があります。
attack() には final が付いていないので、PillarSlayer クラスでオーバーライドできます。
一方、showRule() には final が付いているので、PillarSlayer クラスでオーバーライドできません。
また、static final int MAX_RULE_LEVEL は値が固定されているため、あとから変更できません。
この図から分かることは、final が「何も広げさせないためのもの」ではなく、
自由に変えてよい部分と、守るべき固定部分を分けるためのもの
だということです。
final を鬼滅の刃風に整理する
鬼滅の刃風にたとえると、final は「絶対に破ってはいけない決まり」をコードにしたものです。
| final の使い方 | 鬼滅の刃風のイメージ |
|---|---|
| final メソッド | この技の型は変えるな |
| final クラス | この隊士の型は完成形なので派生させるな |
| final フィールド | この数値は隊の決まりだから変えるな |
オブジェクト指向では、自由に拡張できることは大きな強みです。
でも、本当に読みやすく安全な設計では、自由に変えてよい部分と、変えてはいけない部分が分かれています。
final は、その「ここは固定する」という線を引くための修飾子です。
この内容で押さえておきたいポイント
| ポイント | 内容 |
|---|---|
| final の基本意味 | それ以上変更させない |
| final メソッド | オーバーライドできない |
| final クラス | 継承できない |
| final フィールド | 値を再代入できない |
| static final | クラス全体で共有する定数によく使う |
| final とオーバーライド | 変えてよいメソッドと変えてはいけないメソッドを分ける |
| final と継承 | 派生を許すクラスと完成形のクラスを分ける |
| final と値 | 状態として変わる値と、ルールとして固定する値を分ける |
final を見たときは、「これは何を固定しているのか」と考えると理解しやすくなります。
メソッドならオーバーライドを止めています。
クラスなら継承を止めています。
フィールドなら値の変更を止めています。
この感覚がつかめると、final は単なる制限ではなく、設計を安定させるための大切な道具として見えてきます。
