//fix this/ Javaコードの間違いをさがせ!
このシリーズは、あなたのコーディング・スキルを試すコーナーです。毎号オラクルのJavaエバンジェリストたちが、Javaコードに関する難問を出題し、正解と解説を掲載します。是非、毎号チャレンジして貴方のコーディング能力の向上にお役立て下さい。
Articles
Java
Java技術関連記事
Fix This
このシリーズは、あなたのコーディング・スキルを試すコーナーです。毎号オラクルのJavaエバンジェリストたちが、Javaコードに関する難問を出題し、正解と解説を掲載します。是非、毎号チャレンジして貴方のコーディング能力の向上にお役立て下さい。
『Java Servlet Programming』の第9章にあるコード例 ConnectionPool.javaには、ちょっとしたバグがあります。このコードは何年も問題なく動いていましたが、最近、(※2012/7月時点)JDBCドライバがアップグレードされたため、動かなくなりました。
このプール・クラスのコードの一部を次に示します。このコードの問題点を特定し、プログラム全体を再設計せずに修正してください。
private Hashtable connections = new Hashtable();
private void initializePool(...) ... {
for (int i = 0; i < initialPoolSize; i++)
connections.put(getNewConnection(...), Boolean.FALSE); //false=
使用されていない
}
}
public Connection getConnection() ... {
// ...フラグがFALSEのConnectionを検索...
connections.put(con, Boolean.TRUE);
return con;
}
public void returnConnection(Connection returned) {
connections.put(returned, Boolean.FALSE);
}
以下のうち正しい対処方法はどれでしょうか?
1) Connectionの使用をやめ、代わりにPooledConnectionを使う
2) Hashtableの使用をやめ、代わりにMapインタフェースの別の実装を使う
3) 問題のあるConnection実装を拡張し、いくつかのメソッドをオーバーライドする
4) 問題のあるConnectionをラップするようなConnectionの実装を作成する
<ヒント>
このプール・クラスのバグは、並行処理に関するものではありません。
正解は4)です。ConnectionPool.javaコードでは、hashCode()とequals()はオーバーライドされないという誤った仮定をしていました。このため、新しいドライバへアップグレードすることで、プログラムが壊れてしまったのです。
新しい実装では、デフォルトの参照型等価の代わりに、オブジェクト等価を使用してequals()が実装されたためです。4)の方法では、プログラムをhashCode()およびequals()の実装から完全に独立させることができます。解決策は、実際のConnection実装をラップし、内部でコールをルーティングするConnectionインタフェースの実装を安全に作成することです。それによって、プログラムは常にオブジェクトの信頼性の高いhashCode()およびequals()メソッドを使用することになるでしょう。