[戻る]

Java読書会BOF 「Effective Java 第3版」を読む会 第2回

開催概要
日時 2019年1月19日 10:00 - 17:00
場所 川崎市教育文化会館 第3会議室
出席者(敬称略) 高橋(智)、高橋(徹)、藪下、今井、井上、吉本、平山、遠藤、柴村、岩室(書記)

第3章 すべてのオブジェクトに共通のメソッド

項目13 clone を注意してオーバーライドする

  • Arrays.copyOf(...) vs [].clone()
    • 配列をまるっとコピーしたい → [].clone()
    • 部分的にコピーしたい → Arrays.copyOf(...)
    • どちらもshallow copy
  • Arrays.copyOf(...): 3引数の場合、配列の型を変えることができる。
    • このメソッドは Java6 からなので、Effective Java 第2版(Java5まで)の段階では存在しなかった。
  • "super.clone" vs "super.clone()"
    • 原文でカッコが無いケースは "call super.clone" のように動詞の目的語になっている。
    • 原文でカッコが有るケースは名詞的に使用されている。

項目14 Comparable の実装を検討する

  • p.73 中央付近: 一般論として、比較するときは算術演算を使うな、ということ。
  • JLS: Java言語仕様。(Java Language Specification)

第4章 クラスとインタフェース

項目15 クラスとメンバーへのアクセス可能性を最小限にする

  • p.78: convensionは、「慣習的」よりも「規定」「規約」の方が適切ではないか?
    • 「条約」「協定」が最も近いのはないかと思われる。
    • ソースが module-info.java になるとは限らないが、実行時に module-info.class が読み込まれるのはMUST。(Java仮想マシン仕様を参照)
    • 一般的なJava処理系の範囲では、module-info.java でないとモジュール定義を書けない。
    • 「JLS 7.7 module decrarations」より、ファイルシステム上に置かれている場合は、module-info . 拡張子(java or jav) というファイル名の場合に限りモジュール定義が可能。
  • pp.78-79: モジュール宣言はmodule pathに置かないとモジュールとして取り扱われない。
    • class pathに置くと、モジュールとしては扱われない。(=通常のjarと同じスコープになる)
  • p.79: モジュールは避けたほうがよい? → まだ慣習的なベストプラクティスが確立されていないから?

  • p.79: 参考文献に [Reinhold] がない?

  • Java9のモジュールシステムでは、同一名モジュールの異なるバージョンを管理することはできないとのこと。例えば以下のようなことはできない。

Application -+- ModuleA - ModuleC-1
             +- MoudleB - ModuleC-2

項目16 public のクラスでは、public のフィールドではなく、アクセッサーメソッドを使う

  • 経験的に、finalであってもpublicクラスでフィールドを公開すると後で困ることがある。

項目17 可変性を最小限にする

  • "accessor" がリードオンリーであるという解釈はどこまで通用するのか?
    • "mutator" と一緒に使われている場合はリードオンリーと解釈できるのではないか。
    • RAM(Random Access Memory) や ruby の attr_accessor のケースでは、リードライト両方を含んでいる。
  • BigDecimal, BigIntegerは final ではないため、継承可能である。(!!)

  • 最近のJVM実装におけるGCアルゴリズム(世代別GCなど)および各種の実行時最適化(エスケープアナリシスなど)を考慮すると、不変で生存期間の短かいオブジェクトを毎回作る方が、作ったオブジェクトを再利用するよりも効率が良いと考えられる。

項目18 継承よりもコンポジションを選ぶ

  • Guava → Google Guava。Googleが提供しているApache Commonsのようなライブラリ。
    • 比較的APIの改廃が激しいため、異なるバージョンの Google Guava に依存しているライブラリを複数使うと、バージョン間でのAPI非互換によるトラブルが発生しやすい。

項目19 継承のために設計および文書化する、でなければ継承を禁止する

  • p.95 3段落目: 「慣習として」というフレーズは原文には無い模様。(原文のバージョン違いである可能性あり)
  • p.97: 「継承のために~サブクラスを書くことです。」原文では "subclasses" なので、「複数の」を補った方がよい?
  • p.98: スーパークラスに引数無しコンストラクタがあれば、サブクラスで super() を書かなくても暗黙で呼ばれる。
  • p.98: 「インスタント*2」は実質的に変数instantを指している。Instantクラスが何か知らないと、この箇所や訳注部分の意味がわかりづらいのではないだろうか?
  • サブクラスに定義したメソッドでスーパークラスの振る舞いを変えるようなコードを書くと、pp.97-98 のルールを破ることになるが、そのようなコードを書きたいケースが無いとは言えない。

項目20 抽象クラスよりもインタフェースを選ぶ

  • p.103 L4-5: 「簡単にします。」→原文では斜体で「very」が付いている。

Note

次回は p.106 から。

(以上)

[戻る]