メモリリーク実装例
public class Leak { final private String _value; /** * @param value * */ public Leak(String value) { super(); _value = value; } }
上記クラスを以下のように使用した場合、leakSet.size()の値はいくつになるでしょうか?
Set leakSet = new HashSet(); leakSet.add(new Leak("A")); leakSet.add(new Leak("A"));
答えは2!1ではない!
Set#add,Map#putのキーに同じインスタンスを追加した場合は上書きされる。
上記例では上書きされることを期待しているけど、上書きされずに要素が追加されてしまう。
理由は、Leakクラスにequals,hashCodeメソッドがオーバーライドされていないため、"A"を渡して生成された2つのインスタンスが同一インスタンスと見なされないから。
「そんなの当たり前じゃん!」という人も多いだろうけど、意外とこのことを知らない人がいるみたい。
これは実際に私が遭遇したケースだったりする。
作った本人はSet#addに同じインスタンスを追加する場合に上書きされることは知っていたようだが、同じインスタンスと判断される条件を知らなかったらしい。
もう、会社をやめてしまったけど、こいつ一応「優秀」て言われていたんだよな。
でも、他にもテーブルロックの順番を適当にやっていたがためにデッドロックを発生させたり、DBコネクションのクローズタイミングのミスで、コネクションプールを枯渇させてしまったりと色々やってくれた。
やめるタイミングも一緒にやってたプロジェクトが大火事状態の時だったし、やめる時の挨拶もなかったなあ。
確かに自分もこの時はやめたくなったけど。
奴は今頃どこで何やってんだろ。