[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 11398] Re: Java 1.5 Tiger : A Developer's Notebook



風邪をひいて意識が朦朧としている村山@netgeneです.

boxing/unboxingはまだ囓ってる最中なんで,話の流れを把握
しきれてませんが,
#例の本もamazonで注文中.

>   そうなんです。
>   で、Unboxingされるかと思いきや当然参照の比較になって、

ここはソースの方が参照の比較を行っているからでは.
Integer 型のaとbを比較してますから.

数値の比較をしたければint型のaとbを比較するようなコードを書くべき
でしょう.その場合ならばUnboxingして比較するのでしょう.多分.

>しかもInteger
> クラスのvalueOfメソッドは次のような実装に変わっています。
>    ------- J2SE5.0(JDK1.5)のInteger.javaより引用 ------
>     public static Integer valueOf(int i) {
>       final int offset = 128;
>       if (i >= -128 && i <= 127) { // must cache 
>         return IntegerCache.cache[i + offset];
>       }
>       return new Integer(i);
>     }
>    ----------------------------------------------------
ここの-128〜127でキャッシュするというのは,実装でしょうか仕様でしょうか.
結論から言えば,おそらく実装だと思います.

1.5.0b2(多分)のAPIドキュメントでは,それらしき記述はなく,
"significantly better space and time performance by 
 caching frequently requested values."
と書かれています.
#仕様が変更される可能性もなくはない.

ということは,おそらくこのキャッシュ実装は将来変更されうるもの
ではないでしょうか?(常識的に考えればこのような部分で将来改良
する余地をなくすような仕様は作らないし.)

もしそうだとすると,例の問題の(言語仕様レベルの)答はQ1,Q2共に
「d) JVMの最適化によっては Equal か Not equal のどちらでも
     表示される可能性はある」
になる,ということなのでは.

この場合は,現状の実装では「常に一致する」ということがあっても,
それに依存するコードは実装依存のコードであり,好ましくないと思われ
ます.実装依存なので将来APIの実装が改良された途端に動作がおかしく
なる可能性があります.

#キャッシュするのは,非常に多くのインスタンスを生成する際に,
#...flyweightパターンになるのかな?あれを使って消費メモリや
#インスタンス生成/GCなどのコスト削減を図るのが目的でしょう.
#キャッシュには弱参照やらを使って,不要なインスタンスは
#回収されている可能性もある.特にキャッシュが大きくなればなるほど
#その必要性も高い.

#で,キャッシュするためには,上の条件が「言語仕様」として必要に
#なります.これがもし「常にEqualsである」とかになっていると全Integer
#インスタンスをキャッシュする必要があり,かえってコストが嵩む
#恐れがあります.

#まあ,そもそもStringやIntegerの参照比較って,滅多に使わない
#ですけどね.ほとんどの人は「StringやIntegerでの比較は==ではなく
#equals()を使わなければならない.」とだけ丸暗記してることでしょう.