[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[jfriends-ml 10128] Re: Effective Java 第 1 回議事録
こんにちは、
初めて投稿します。「Effective Java」を訳した柴田です。
議事録の内容について、いくつか、質問、補足をさせてください。
> ◆はじめに
> 今回から、2002年のJolt賞を獲得した話題の書を読みはじめました。
> 参加者の方も18名にもおよび大変賑やかな読書会となりました。内容が
> 濃いためになかなか読み進められませんでした。あと5,6回は開催すると
> 思います。
薄い本ですが、内容は、明らかに初心者向けではないです。
> P XII
> Doug Lea 氏の名前が登場するが、以前、SunのWebサイトにてDoug Lea 氏と
> ライブでチャットできたそうです。Doug Lea 氏の著書についての質問とかも
> できたようです。
> また、JSR166 にて Concurrency Utilities という規格が提案されているそ
> うです。
> http://gee.cs.oswego.edu/dl/concurrency-interest/jsr166-28jan02-4up.pdf
Doug LeaがSpecification Leadとして、リリース1.5(Tiger)に入れるべく活動し
ているようです。
> P6
> ==演算子について書かれているが、==演算子の使用を勧めているのか?
> --> java.lang.String の処理が重いので、==演算子を使う価値あり
> --> プロファイラツールのOptimizeitを使って、ボトルネックがString
> の処理である事を発見したことがあった。
本文にも書かれていますが、クラスがa==bの時だけa.equals(b)が成り立つこと
を保証すれば、equalsメソッドの代りに==演算子を使用することが可能になると
いう説明であり、典型的な例としては、本文に書かれている項目21のタイプセー
フenumを見た方が、より何を言っているのか理解しやすいと思います。
> P7
> staticファクトリメソッドは、JDBCやJAXPでも使われている
> --> C++でも「staticファクトリメソッド」は実現出来るのか?
> --> できない、もしくは、とても難しい
> --> C++には動的クラスロードがあるのか?
このC++でstaticファクトリメソッドが実現出来るかという問いに対して、「で
きない、もしくは、とても難しい」とあるのは、おそらく、サービスプロバイダ
ーフレームワークのように動的にクラスをロードして、インスタンスを生成可能
かという意図の議論ではないかと推測しますが、どうなのでしょうか?
Javaでは、動的なクラスのロードや、スレッドの機能などが、言語として取り込
まれていますから、単純にC++と比較すると、C++にはスレッドの機能やクラスの
動的ロードがないという結論になってしまうと思います。しかし、C++であれ
ば、その無い機能を補っているのはOSであったり、ライブラリーであったりしま
す。
例えば、C++であっても、クラスの実装を、(Solarisであれば)shared objectに
し
ておいて、shared objectのファイル名とインスタンスを生成する関数を明示す
ることで、動的にロードして、あるインタフェース(C++の場合は、単なる抽象ク
ラスに過ぎませんが)を実装したインスタンスを返すということをやったりする
ことも可能です。この場合、言語だけでなく、OSが提供しているライブラリーと
組み合わせることで可能となります。
> ■ 項目4(重複したオブジェクトを生成するのを避ける)
>
> P13
> public String(String str) というコンストラクタを使っている例を良く見かける
>
> public String(String str) のコンストラクタがあるのは何故だろう?
> --> 明示的にインスタンスを分けたい場合に使うのではないか
> --> 文字コード変換に使えるのではないか
Stringクラスのコピーコンストラクタについては、p.64の第2段落に使用される
べきではないと、解説されています。
> JavaプログラマがC++のコードを書くと、インスタンスの生成を忘れてしまいがち
> --> ポインタ渡しや参照渡しを正しく使い分ける必要もある
インスタンスの「解放」を忘れてしまいがち、の間違いでしょうか?
C++の場合には、明示的にdeleteオペレータを呼び出して解放する必要がありま
すので、誰が解放する責任を持つのか明確に分かるようなメソッドの命名規則を
決めておかないと、誰か解放すべきなのかが、コードを読んでもすぐには分から
なかったりします。
> P23
> 「エンクロージングクラス」「エンクロージングインスタンス」とは?
> --> 意味は?
> --> 日本語の訳語は?
> --> なんとなく感じはわかるのだが...
「enclosing class」と「enclosing instance」が元の英語で、JLS(Java言語仕
様)やJPL(プログラミング言語Java)で使用されています。JLSの翻訳本では、
「囲んでいる」と訳されているのですが、JPLでは「エンクロージング」とカタ
カナ表記にしたので、Effective Javaでもその訳語を使用しています。
ネストしたクラスを含んでいるクラスは、そのネストしたクラスを囲んでいます
ので、エンクロージングクラス(enclosing class)と呼びます。staticではない
ネストしたクラスのインスタンスには、必ず関連付けされたエンクロージングク
ラスのインスタンスが存在しますので、それをエンクロージングインスタンス
(enclosing instance)と呼びます。
例えば、
class Outer {
....
class Inner {
...
}
}
の場合、ネストしたInnerクラスのエンクロージングクラスは、Outerです。ま
た、Innerクラスのインスタンスが生成された時点で関連付けされているOuterク
ラスのインスタンスは、エンクロージングインスタンスです。
> Singletonクラスの中に、ファイナライザを書くことによって、Singletonクラスの
> ガベージコレクションが防げるのではないか?
> --> 実験してみる価値あり!!
確か、1.2からはシングルトンのクラスのインスタンスは、ガーベッジコレクシ
ョンされないと思いますが。つまり、Classオブジェクト自身が、1.1まではガー
ベッジコレクションされることがあったのですが、1.2からはガーベッジコレク
ションされなくなったと記憶しています。
> P37
> 17と37とが採用されている理由は?
> --> ハッシュテーブルのサイズに近い値?
> --> 統計学的に推奨されている数字なのか?
> --> 情報求む!!
私も正確には分かりませんが、多分、17は特別な意味はないと思います。本文に
も書いてあるように、ゼロでないことが意味があるのだと思います。例えば、次
のFooクラスとBarクラスを考えて見てください。
class Foo {
private int x;
private int y;
....
}
class Bar {
private int x;
private int y;
private int x;
....
}
もし、17ではなく、ゼロを用いると、FooクラスとBarクラスのインスタンスがあ
ったとして、すべてのフィールドがゼロだとすると、ハッシュコードは、どちら
もゼロになってしまいます。しかし、ゼロ以外の定数であれば、仮にすべてのフ
ィールドがすべてゼロであっても、フィールドの個数に応じてハッシュコードが
異なるものになります。
素数37が選ばれている理由は、本文でも「明確でない」と述べられていますが、
仮に32を選んだとします。32は、素数でない偶数です。そうすると、32を掛ける
ことは、実際には左に5ビットシフトすることになります。つまり、
result = 32*result + c;
の計算式で、話を分かりやすくするために、cが31以下だったとすると、7回この
計算を行うと、一回目のresultの情報は、完全に消え去ることになります。そう
すると、一回目のresult計算に用いられたフィールドは、ハッシュコードの計算
に全く寄与しないことになります。これでは、都合が悪いわけです。
> ◆ さいごに
> 翻訳者の柴田さんには、東京近郊にお住まいであれば、読書会に参加いただけ
> るように交渉してみようかしら、と思ったりしてます。
> 幸い6月は午後のみの開催となりそうですし、ちょっとだけでも顔を出していた
> だけるとうれしいな...
横浜市青葉区に住んでいます。より、分かり易く(?)言えば、「こどもの国」の
近くです。都合が付けば、参加してもいいですよ。
柴田芳樹