Java.util.scannerクラスが「ファイナル」と宣言されたのはなぜですか?
解決
おそらく、それを拡張し、そのいくつかの方法を上書きすることはおそらくそれを破るからでしょう。また、メソッドの上書きを容易にすることは、内部の作業の多くにさらされるため、将来、それらを変更することを決定した場合(パフォーマンスやその他の理由で)、すべてのクラスを壊すことなくクラスを変更することが難しくなります。それはそれを拡張します。
たとえば、クラスの次の方法を検討してください。
public boolean nextBoolean() {
clearCaches();
return Boolean.parseBoolean(next(boolPattern()));
}
「Awesome」を「何らかの理由で)「真の」ブール値に評価したいので、これを上書きしたいとします。上書きすると、super.nextboolean()を呼び出すことはできません。デフォルトロジックを使用して次のトークンを消費するからです。ただし、super.nextboolean()を呼び出さないと、ClearCaches()が呼び出されず、おそらく上書きのないメソッドを破壊する可能性があります。 clearcaches()はプライベートであるため、呼び出すことはできません。彼らがそれを保護したが、それがパフォーマンスの問題を引き起こしていることに気付いた場合、もはやキャッシュをクリアしない新しい実装を望んでいた場合、彼らはあなたの上書きの実装を破るかもしれません。
基本的には、クラス内の隠された部分を簡単に変更できるようになります。クラス内の隠された部分は非常に複雑で、壊れた子供のクラス(または簡単に壊れる可能性のあるクラス)を作ることからあなたを守ることができます。
他のヒント
セキュリティ上の理由によるものだと思います。このクラスはユーザーの入力を読み取り、悪い意図を持っている人がそれを拡張し、動作を変更するとねじ込まれます。最終的な場合、悪者にとってはそれほど簡単ではありません。なぜなら、彼が自分のタイプのスキャナー(java.util.scannerではなく)を作ると、多型の原則が壊れるからです。悪者がリモートサーバーでこれを自動的に行うボット/スクリプトを書くのに十分なスマートであることができます...彼はコンパイルされたアプリケーションで動的なクラスロードによってそれを行うことさえできます。
あなたが提供したリンクはそれをすべて説明していると思います。
あなたの場合、とにかく継承の代わりに構成を好むべきだと思われます。事前定義された動作を持つユーティリティを作成しており、スキャナークラスの詳細の一部(またはすべて)を隠すことができます。
動作を変更するために継承を使用した多くの実装を見てきました。最終結果は通常、モノリシックなデザインであり、場合によっては契約の破損、および/または壊れた行動でした。