読書会(Effective Java (Second Edition))第2回議事録

[ 戻る ]


--------------------------------------------------------------
Java読書会 「Effective Java(Second Edition)」を読む会 第2回

日時 : 2008/9/27(土) 10:00-17:00
場所 : 川崎市教育文化会館 第一会議室
出席者:高橋(徹)、前山、遠藤、江本、高橋(智)、小棚木(書記)、尾関、吉本、
岩室、
村山、石黒、松永、高江洲、根本
今回の範囲:P24〜P61(Item6〜Item11)

Item6
Javaでもメモリリークは起こりうる
ヒーププロファイラツールを使用して確認する

・上書きされた要素はGCの対象となるのか?
→ 上書きされた要素はGCの対象となる。ここで問題なのはその要素が上書きされ
るまで
参照が保持されることだ。(上書きされなければ、メモリリークとなる)

・初版から「現在のJVMの実装では変数が定義されているブロックから抜けるだ
けでは
十分でなく・・・」の文が消えているが、JVMの実装が変更されたのか?
→ Runnableを実装していると、ずっとループしているので改善された可能性はある。
→ 2重ループを使えば確認できそうだ

・WeakHashMapはキーに参照を保持する。
・WeakReference、SoftReference、PhantomReferenceの違いがよくわからない。
→ Java魂の説明がわかりやすい?
→ 宿題!!

・P25の「More Commonly」以下が第2版で別段落になった

Item 7
finalizerは挙動が予測できない。危険。ほぼ不必要。

・destructorをちゃんと書くとは?
→ terminationするの間違い。(レジュメの間違い)

・Fooのインスタンスをブロックの外に書いているのはなぜ?(P29)
→ ブロック内に書くと例外情報が上書きされるから?
→ 通常は以下のようなコードを書くと思う。
Foo foo;
try {
foo = new Foo();
} finally {
if(foo != null) {
foo.terminate();
}
}
→ 説明のために省略しているから?

・native peerって何?(P29)
→ AWTで使われていて、nativeメソッドを呼び出す仕組み

・匿名クラスでfinalizeを実行する(P30)
→ finalizeメソッドがオーバーライドされないので、必ず実行される。
→ finalizeは何度呼ばれても大丈夫なようにすべき
→ 非Finalなクラスならガーディアンの導入を検討すべき

・解放されるときに順序依存が発生しないか?
→ 順番は保障されない。
→ try-finallyなら解放処理の順序は保障できる。

・finilizeメソッドを書くことはあるか?
→ 解放処理を(try-finallyなどで)必ず実行するようにすると不要
→ AWTでは(nativeの解放のために)やっているのでは?

・どうやって検出する?
→ ヒーププロファイラ使わないとわからない

雑談:JDKをFindBugsにかけたらどうなる?

Item 8
・contractの訳は「契約」が一般的?
→ 「規約」という訳じゃだめ?
→ 「契約」は「規約」よりももっと意味が強い。

・JavaDocでは「general contract」が「汎用規約」になっている。

・eaualsメソッドでgeClass()を使うことでサブクラスとの比較を防ぐ。
しかし、これはLiskovの置換原則に違反する。

・フィールドを増やしていないので、PointクラスとCounterPointは入れ替えても
問題はないはずなのに、LSPに違反する。(2版でサンプルが追加された)

・初版では「側面」という訳になっているが、2版では変わっている?(P41)
→ "an aspect"が"a value component"に変わった。
初版
you can add an aspect to a subclass of an abstract class ...
2版
you can add a value component to a subclass of an abstract class ...

・java.net.URLのequalsは同じ結果を返すとは限らない

・canonical form
→ 正規形
→ URLの相対パスの比較
(/hoge/foo/../bar と /hoge/barはcanonical formは等価)
→ シンボリックリンクの比較

・@OverrideがJDK6からinterfaceのメソッドに適用できるようになった。

Item 9
・equalsをオーバーライドしたらhashCodeをオーバーライドする
→ hashCodeのみをオーバーライドしてもよい?
→→ 契約を満たしていれば、オーバーライドしてもよいが、
それはこのItemでの議論の対象ではない。
(※ 第2版ではItemのタイトルに"When overriding equals"が追加されています。)

・new Object()で作られた2つのオブジェクトのhash値が同じになることはあるか?
→ 確率的にはない。

・hashCodeのレシピ(P48)
初版では37を使っているが、2版では31を使っている
→ 掛け算をシフトと引き算に置き換え可能なので、パフォーマンスがよい。

・hashCodeが0のときはある?あるなら毎度計算してしまう。(P49)

・hashCodeの作成を支援するライブラリ/ツールはあるか?
→ 宿題

Item 10
初版と大きく主張の異なる部分はない。
サンプルがString.format()を使うように変更された。

Item 11
・インタフェースの使い方として普通ではない。
→ Cloneableはマーカーインタフェースだが、Objectにclone()が実装されている。
→ 普通はClonable { Object clone(); } のようになると思う。

・CloneNotSupportedExceptionをAssertionErrorに変換している。
→ cloneメソッドをオーバーライドしているなら、Cloneableは必ず実装している
はず。
CloneNotSupportExceptionはチェック例外なのでtry-catchが必要。
→ clone()時はコンストラクタを呼ばない?
→ Listはcloneできないが、ArrayListはcloneできる。Cloneableを実装している
のはArrayList

コピーコンストラクタ
C++だとビットコピー

以上


[ 戻る ]