【Java】final修飾子 ( 定数化・継承禁止、オーバーライド禁止 )

# final修飾子

final修飾子 は「**変数 を 定数 に変えたり、元のクラスや[メソッド]の機能を変えないための修飾子。**」です。

具体的に言うと

- **[クラス]に付けた場合その[クラス]を[継承]することができなくなる**
- **[メソッド]に付けた場合、その[メソッド]を[オーバーライド]することができなくなる**
- **変数に付けた場合、その変数は 定数 となる**

といった使い方ができます。

## 固定にする理由

- 後から修正がかかった際、一か所を直せば済むから
- ソースの可読性が高まるから
- 変更されたくない値を変更されない様にするから

## 固定にするもの

[メソッド]のパラメーターや、[メソッド] のローカル変数 において、
条件分岐ごとの処理による値の書き換えの可能性が無いような場合は、 final で定義するほうがよいです。

具体的に「どんなものを定数にするか」ということですが、例を上げると

- 固定の文字列
- ダイアログなどのメッセージ
- サイトのURL
- 税率のような基本的に変わらない値

などがパッと思いつきました。

## 定数を定義する

**「変数として扱う必要がない場合は、「 final 」をつける癖をつける。」**
ソースを書いていて何度も使うものは変数にしますが、その中でも**「固定にするべき」**ものは、定数化しましょう。

- 変数は「値が変わるもの」
- 定数は「値が固定であるもの」

### 定数の命名規則 (SNAKE_CASE)
**「SNAKE_CASE(スネークケース記法: すべて大文字とアンダースコア)でかくこと。」**

定数は 変数特別するため、「 MY_NAME 」のような、すべて大文字で単語の書き方をしてください。
もちろん予約語はつかわないように。
暗黙的に「 **public static finalで修飾される** 」とセットで覚えておくといいかもしれない。

【定数を定義したクラス】

```java
class ClassFinal {
    // 変数に final を付与して 定数化。（大文字にすること）
    public static final String MESSAGE = "定数です";

}
```
【定数を上書きしようとするクラス】

```java
class FinalMain {
    public static void main(String[] args) {
        ClassFinal.MESSAGE = "定数を変えようとするとエラーになります";
    }
}
```
【実行結果】

```
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	final フィールド ClassFinal.MESSAGE には代入できません
```




### 定数を定義する場所

個々のファイルへ定義するより、「CommonConstant.java」みたいな、定数専用の[クラス]を用意して、まとめて定義することが多い。

## クラスにつける

[クラス]にfinal修飾子を付けると、
そのクラスは[継承]することが出来なくなり、コンパイルするとエラーとなります。

【finalにした親クラス】

```java
final class ClassFinal {
    String message = "finalクラスです";
    public final void printMessage() {
        System.out.println(this.message);
    }
}
```
【継承しようとする子クラス】

```java
public class ClassFinalChild extends ClassFinal {
    //処理 ...
}
```
【呼び出そうとするクラス】

```java
class FinalMain {
    public static void main(String[] args) {
        ClassFinalChild cfc = new ClassFinalChild();
    }

}
```
【実行結果】

```
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	型 ClassFinalChild は final クラス ClassFinal をサブクラス化できません
```

## メソッドにつける (オーバーライド)

[メソッド] につけると、その[メソッド]は子[クラス]での[オーバーライド]ができなくなります。

【メソッドをfinalにした親クラス】

```java
class ClassFinal {
    String message = "finalクラスです";
    //メソッドに final を付与
    public final void printMessage() {
        System.out.println(this.message);
    }
}
```
【継承しようとする子クラス】

```java
public class ClassFinalChild extends ClassFinal {
    public void printMessage() {
        System.out.println(this.message + "をオーバーライドします");
    }
}
```
【呼び出そうとするクラス】

```java
class FinalMain {
    public static void main(String[] args) {
        ClassFinalChild cfc = new ClassFinalChild();
    }

}
```
【実行結果】

```
スレッド "main" での例外 java.lang.VerifyError: クラス practice_final_and_statc.ClassFinalChild は、最終メソッド practice_final_and_statc.ClassFinal.printMessage()V をオーバーライドします。
```

## 参考文献・記事


- [Java言語の命名指針](https://qiita.com/rkonno/items/1b30daf83854fecbb814)

- [【PHP】誰も教えてくれないconst（定数）の上手な使い方]
- [Progate]
- [ドットインストール]
- [javaのfinal修飾子
](https://qiita.com/ryo2132/items/eb9a63f2b107c1d6b25c)

[Progate]:https://prog-8.com/
[ドットインストール]:https://dotinstall.com/
[【PHP】誰も教えてくれないconst（定数）の上手な使い方]:https://rightcode.co.jp/blog/become-engineer/php-const





[インスタンス]:https://qiita.com/takahirocook/items/ec01cdcbb440cf0d1cc4
[インスタンス化]:https://qiita.com/takahirocook/items/ec01cdcbb440cf0d1cc4
[アクセス修飾子]:https://qiita.com/takahirocook/items/e51b0b9d37d95ad587fe
[フィールド]:https://qiita.com/takahirocook/items/28df75a133049a74ece1
[フィールド変数]:https://qiita.com/takahirocook/items/28df75a133049a74ece1
[new演算子]:https://qiita.com/takahirocook/items/00f9f97592bf50831d39
[カプセル化]:https://qiita.com/takahirocook/items/e469a7c0539a0012868e
[クラス]:https://qiita.com/takahirocook/items/50cbbdca8e21539170e9
[メソッド]:https://qiita.com/takahirocook/items/5bfe43576d87a2a4006c
[mainメソッド]:https://qiita.com/takahirocook/items/f4635915337303de338c
[メソッドの呼び出し]:https://qiita.com/takahirocook/items/f4635915337303de338c
[コンストラクタ]:https://qiita.com/takahirocook/items/fa1822f2f22c3786593e
[引数]:https://qiita.com/takahirocook/items/5e5b0ba79e869f4a592e
[戻り値]:https://qiita.com/takahirocook/items/3b6fa670a1d6dd4a9386
[this]:https://qiita.com/takahirocook/items/d251ec4693c68f6b9538
[getter・setter]:https://qiita.com/takahirocook/items/27828bc8477735612021
[setter]:https://qiita.com/takahirocook/items/27828bc8477735612021
[getter]:https://qiita.com/takahirocook/items/27828bc8477735612021
[オブジェクト指向]:https://qiita.com/takahirocook/items/041ba7a096b71ab8ffd4
[継承]:https://qiita.com/takahirocook/items/6c84ea66a6e2ad536a37
[オーバーライド]:https://qiita.com/takahirocook/items/09dd8e5f56d6617ce45a
[オーバーロード]:https://qiita.com/takahirocook/items/b937c3c07126fe7e02a4
[this]:https://qiita.com/takahirocook/items/d251ec4693c68f6b9538
[super]:https://qiita.com/takahirocook/items/75a07131e7e791c8442c