2011-12-19 4 views
52

、:javadocのDouble.valueofが値をキャッシュする理由は何ですか?方法のためのOpenJDKで

public static Double valueOf(double d) 

のjavadocは言う:指定されたdouble値を表すDoubleインスタンスを返します

を。新しいDoubleインスタンスが必要ない場合、頻繁に要求される値をキャッシュすることにより、このメソッドは空間と時間のパフォーマンスが大幅に向上する可能性があるため、Double(double)コンストラクタより優先されます。

public static Double valueOf(double d) { 
    return new Double(d); 
} 

キャッシュが嘘である:

は、ここで実際のコードです!何が起きてる?

+31

ドキュメントは常に間違っています。それを覚えている –

+5

どこからコードを取得しますか? OpenJDK6? OpenJDK7? Apache Harmony? GNUクラスパス? – scravy

+0

@scravy私はOpenJDK7を見ていますが、公式のSunリリースではこのコードは何年も変わっていません。 –

答えて

54

IntegerLongBigDecimalなどとマニュアルは、常に同じである:(定義されていない)いくつかの状況下では、方法は、同じ結果を返すことができます。

AFAIKでは、キャッシュは整数型に対してのみ実装され、-128と127の間の値(最も一般的な値)のキャッシュされたインスタンスを返します。 BigDecimalの場合、キャッシュは現在0〜10の値で動作します。

より新しいバージョンのJava の場合は、はこの動作を他の値/種類に拡張できます。だから、このコードを明日より速くするかもしれないので(今日のコードは遅くならないので)、このコードを使うのは賢明です。

たとえば、Javaコンパイラは、自動ボックス用のコードを生成するときにこのAPIを使用します。

6

APIの設計者は、おそらく代替実装を制限したくないと考えていました。これで、Doubleクラスにキャッシングを自由に追加できます。

29

APIドキュメントと間違って何もありません:

この方法は、実装がされており、ここではキャッシング行うことが許可されていることを...

を得可能性があります単純にコンストラクタでは不可能です。ただし、必須ではありません。ただし、キャッシュを実装する実装がある可能性があるため、コンストラクタを使用するよりもこのメソッドを優先する必要があります。この方法は、多くの種類のために存在

+4

+1。 IMHO、重要な点は、OPが "*実際のコード"を書くことですが、彼が提供するものは単なる実装*です。他のプラットフォームでは、他の実装も存在する可能性があります。 (特に、ファームウェアの実装でここでの違いを見るのは驚きではありません) – ruakh

+0

@ruakh代替の実装には別のjavadocも付いてくると思います。コードとjavadocが一緒になって、それは高水準の仕様書ではないはずです。それはコードには属しません。 –

+7

java *クラス*のjavadocは*仕様です。他のものはJava実装を記述するOracle以外のベンダーであり、これらすべてのクラスに対して同じ機能を提供する必要があるためです。 –

2

これらのvalueOf()メソッドは、キャッシングをサポートする目的ですべての数値型に存在します。実際には、Doubleの場合、キャッシュは使用せず、IntegerLongの場合にのみ使用します。

12

は、Java 1.5以降からは、JVM/JITは、だから、Integerのために好ましいアプローチはvalueOfを使用することである理由であるInteger S -127〜127のキャッシングを保証します。 doubleのコンストラクタの使用には、通常、valueOfを使用する必要があります。これは、JITが、最適なコードを最適化できるためです。たとえば、次のループ考慮してください。この例では

for (Object o: objectList) { 
    o.setValue(Double.valueOf(0.0)); 
} 

をごnew Double(0.0);を使用した場合、それができなくなり、一方、JITは、二重のオブジェクトを事前計算し、ループの各反復で同じ値を再割り当てすることができますそれをする。

+0

+1はキャッシュの使用例を強調表示しています。 – Luke

+2

おめでとう、2013年の担当者、幸せな新年2013 :) –

+0

@MohamedSakherSawanありがとう - それは私の一日を作った:) – Deco

2

JVMは組み込みデバイス(主に)のコードサイズを削減するために作成されたことを覚えておいてください。これはセットトップボックスのオペレーティングシステムです。私はいくつかの組み込みJavaプラットフォームに取り組んできましたが、valueOfの「価値」がより明白になることがありますが、場合によってはかなりのスペースを節約できます。

"new"はキャッシュされたインスタンスを使用できないため、ほとんどの方法があります。 valueOfはキャッシュされたインスタンスを使用するように実装されるかもしれません(そうでなければ常に新しいものを使用するでしょう)。

実際にキャッシュ値をキャッシュしたメソッドで置き換えた場合、すべてのコードでその変更の利点が得られますが、 "valueOf"のようなメソッドを用意することはありません(まあ、実際には決して - コンパイラ/バイトコードの実行者を微調整してキャッシュされた値を返すことができますが、いくつかの契約を破ると思います)

キャッシュは本当にうそではなく、心の状態です。

+2

jvmの理由についての声明への言及はありますか?valueOfメソッドは新しいもので、オートボクシングをサポートします。これらのコンストラクタは決してあってはいけません。 – stolsvik

関連する問題