オーバーライド可能なメソッドを readObject() メソッドから呼び出すと、復元処理を完了する前のサブクラスの状態を、オーバーライドしたメソッドから読むことができる。これは、ベースクラスの復元が最初に行われ、その後にサブクラスの復元が行われるからである。そのため、readObject() はオーバーライド可能ないかなるメソッドも呼び出してはいけない。
このトピックに関連して「MET06-J. clone() からオーバーライド可能なメソッドを呼び出さない」も参照せよ。
違反コード
以下の違反コード例では、readObject() メソッドからオーバーライド可能なメソッドを呼び出している。
private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException { overridableMethod(); stream.defaultReadObject(); } public void overridableMethod() { // ... }
適合コード
以下の適合コードでは、オーバーライド可能なメソッドの呼び出しを削除している。メソッド呼び出しを削除できないならば、メソッドを private 宣言あるいは final 宣言せよ。
private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); }
例外
SER09-EX0: オーバーライド可能なメソッドではあるが、java.io.ObjectInputStream クラスの defaultReadObject() や readFields() メソッドは、readObject() メソッドから呼び出してもよい[SCG 2009]。
リスク評価
readObject() メソッドからオーバーライド可能なメソッドを呼び出すと、初期化エラーを引き起こす危険がある。
ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
SER09-J | 低 | 中 | 中 | P4 | L3 |
関連ガイドライン
Secure Coding Guidelines for the Java Programming Language, Version 3.0 | Guideline 4-4. Prevent constructors from calling methods that can be overridden |
参考文献
[API 2006] | |
[Bloch 2008] | Item 17. Design and document for inheritance or else prohibit it |
翻訳元
これは以下のページを翻訳したものです。
SER09-J. Do not invoke overridable methods from the readObject() method (revision 52)