ProgrammingJava開発者

Javaのfinalメカニズムは変数、メソッド、クラスでどのように機能し、この修飾子の誤用によってどのような予期しない影響を引き起こす可能性がありますか?

Hintsage AIアシスタントで面接を突破

回答。

finalはJavaで以下のように使用されます:

  • 変数 — 初期化後は変更できなくなる;
  • メソッド — 継承先でオーバーライドできない;
  • クラス — 継承できない。

特性と細かい点:

  • final変数は宣言時またはコンストラクタ内で初期化する必要があります;
  • final参照は参照を変更できませんが(immutableでない場合)、参照先のオブジェクトは変更できます;
  • finalクラス(例えば、StringMath)からの継承は不可能;
  • finalメソッドはオーバーライドできません、たとえクラスが継承可能であっても。
final class A {} // class B extends A は不能 class Parent { final void foo() { } } class Child extends Parent { // void foo() {} // エラー: fooをオーバーライドできない } final int COUNT = 10;

ひっかけ問題。

final変数が参照しているオブジェクトの状態を変更できますか?

回答: はい、immutableオブジェクトでない場合です。例えば:

final List<String> names = new ArrayList<>(); names.add("Vasya"); // 許可されている — 参照に従ったオブジェクトは変更されるが、参照自体は変わらない names = new ArrayList<>(); // コンパイルエラー

このテーマの細かい点を知らないための実際のエラー例。


物語

ログシステムで唯一のfinal Loggerが全コードに渡され、オブジェクトが完全に保護されていると考えられていましたが、公開メソッドを通じて設定が変更され、グローバル設定を壊しました。

物語

ユーティリティクラスでList型のfinalフィールドを作成し、その後それらを外部に返そうとしました。外部コードは取得した参照を通じてリストの内容を簡単に変更しました — finalはこれを防ぐものではありません。

物語

finalクラスに基づいた外部APIを拡張する必要が生じました。それらのため、拡張が不可能になり、ロジックを複製し、二つの独立した製品のブランチを維持する必要があり、移行が難しくなりました。