Effective java 3版 読書会 2日目

実施日時:2018/11/28 22:00~23:30
対象範囲:項目8~項目10
参加者:こなやん、yodai、yoridori、まさや、やぎた、kassyi
形式:オンライン(discord)
   課題本を事前に読み、実業務と照らし合わせて記述内容の
   議論をする。

項目8 ファイナライザとクリーナーを避ける
ファイナライザやクリーナーを使用した経験は有るのか?
⇒参加者の中で、使用した経験が有る人は居なかった。
指定のタイミングで実行されるわけで無いので、オートクローズを使用するべき。
基本的に、いつ実行されるか不明なので使用しない方が良い。
Java9でDeprecated(非推奨)となった。

基本使わない事になっているので、
特に議論する内容は無い。
以降、本項目の様に議論することが少ないものは飛ばすことにする。

項目9 try-finallyよりもtry-with-resourcesを選ぶ
try-catch-finallyを使用する場合、ネストしていると読み辛くなる。

try-with-resourcesを使うとクローズ漏れが無い。
手作業でのClose処理を代行してくれる。
try-with-resourcesは、Java7から使用されているので古いバージョンのJavaを使用する場合は注意が必要。
AutoCloseを実装しているクラスで、外部の資源を利用する場合に使用できる。
0除算など、AutoCloseを実装しているクラスを使用しない場合コンパイルエラーとなる。
try-with-resourcesを使用できるのは、AutoCloseを実装しているクラスのみ。

JavaDockでは、JDBCやJSQLコネクションでも使用可能な模様、Streamでも使用できる。
ソケットでは、AutoCloseAbleを実装していないので、JavaNet系では使用できない模様。
URLコネクションでも使用できない模様。

P38ではcatchを使った例があり、catchを使用して例外を処理できる。

tryのかっこの中にクローズ処理をまとめて書く様にできている。

try-finallyについて、ワントランザクションごとに一つのtry-finallyが存在する。
finally内でclose処理にtry-finallyを使用する事でネストする場合がある。
finallyはthrowが出来ないので、ログに吐き出すしかない。
経験上、close処理でエラーになった事は無い。

try-with-resourcesを使用してみて、コンパイルエラーとなったらtry-finallyを使う姿勢で良いのかとも思える。

項目10 equalsをオーバーライドするときは一般契約に従う
equalsをオーバーライドして手作業で実装する場合は、論理的等価性を実現する時くらいしかない。
例えば、数字の11と0011を等しいものとする場合などにequalsで等価にする処理を実装する。

ArrayListに追加されているクラス変数をcontainsで比較する際に使用できる。
そうでないと、ループを回して一個一個チェックする必要がある。

equalsとhashcodeのオーバーライドはセットで実行する。
hashcodeのオーバーライドを忘れると、デバッグしても見つけられない。
hashcodeのオーバーライドの必要性は、知っていないと分からないで気を付けるべき。

equalsをオーバーライドする際、手で書く事は少なく、IDE(eclipse)に任せる事が多い。
⇒自動実行した結果をそのまま使うと、思わぬところでバグが出る事もある。
 例えば、HashMapのキーのみの比較を行いたい場合に、データまで比較する結果となり、キーが同じかチェックする場合、(キー:1,データ:abcd)と(キー:1,データ:ccdd)が異なると出力されることが有る。
 内容を見て(比較するフィールドを見て)確認する事。

対称性:
 バリデーションチェックに使えそう。
 禁止文字、記号などのチェック用に一方向のチェックで使えることもある。
 しかし、双方向でないと開発者が意図しない形で動く可能性がある。
 42Pでqualseの対称性を破っている例がある。

推移性:
 P44に記述されているとおり、equalsの契約を守ったまま値要素を追加する方法は無い。
 解決策として、P46にあるとおり単純に値を追加するのではなく、対応するオブジェクトをコンストラクタで実行する。
 オブジェクトの中にあるequalsを使って評価する。
 変数が増えると契約を破る可能性が高くなる。
 同時に、hashcodeのオーバーライドにも影響される。

整合性:
 ホストとIPアドレスの関係など、時間の関係で変化する可能性があるものは外した方が無難
 ⇒P47信頼できない資源に依存するequalsを書いてはいけません
 整合性が時間の経過によって変更されているものはダメ。
 DBのデータについて、DBがから取って来たデータについては、equalsで比較した場合の動作はfalseになる必要がある。
 equalsから例外を投げてはいけない、trueかfalseのどちらかを投げるしかない

P49正規系とは?
⇒Unicode正規化の事?
 Unicode正規化した後に文字列の比較をする事を言っているのかも?

結論:
 equalsは必ずオーバーライドする必要は無い
 ListのcontainsやHashMapを使いたい場合以外は実装しない方が良い、実装するなら注意して実装する。
 また、単体テストを実行する事。

協力:Tech Baton
https://tech-baton.studio.design/

この記事が気に入ったらサポートをしてみませんか?