2011-12-19 8 views
52

W OpenJDK, dla metody:Dlaczego wartość Double.value javadoc mówi, że buforuje wartości, a kiedy nie?

public static Double valueOf(double d) 

Javadoc mówi:

Zwraca podwójne wystąpienie reprezentującą określoną wartość podwójne. Jeśli nowa podwójna instancja nie jest wymagana, ta metoda powinna być zasadniczo używana w stosunku do konstruktora Double (double), ponieważ metoda ta prawdopodobnie przyniesie znacznie lepszą wydajność w przestrzeni i czasie poprzez buforowanie często żądanych wartości.

Oto rzeczywisty kod:

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

Pamięć podręczna jest kłamstwem! Co tu się dzieje?

+31

Dokumentacja jest zawsze błędna. Zapamietaj to. –

+5

Skąd bierzesz kod w każdym razie? OpenJDK6? OpenJDK7? Apache Harmony? GNU Classpath? – scravy

+0

@scravy Patrzę na OpenJDK7, ale ten kod nie zmienia się od lat w oficjalnych wydaniach Sun. –

Odpowiedz

54

Sposób istnieje wiele typów: Integer, Long, BigDecimal i innych i dokumentacja jest zawsze taki sam: W pewnych okolicznościach, (które nie są zdefiniowane poprzednio), przy czym sposób może zwrócić ten sam rezultat.

AFAIK, buforowanie jest realizowane tylko dla typów całkowitych i zwraca wartości z pamięci podręcznej dla wartości od -128 do 127 (najczęstsze wartości). Dla BigDecimal, cache obecnie pracuje dla wartości od 0 do 10.

nowszych wersjach Java może przedłużenie tego zachowania do innych wartości/więcej typów. Więc mądrze jest użyć tego kodu dzisiaj, ponieważ może on sprawić, że twój kod będzie szybszy jutro (a kod nie będzie wolniejszy dzisiaj).

Kompilator Java na przykład używa tego interfejsu API podczas generowania kodu do autoboxingu.

6

Projektanci API prawdopodobnie nie chcieli ograniczać alternatywnej implementacji. Teraz można dodać buforowanie do klasy Double.

29

Nie ma nic złego w doc API:

Ta metoda prawdopodobnie uzyskując ...

Oznacza to, że realizacja wolno robić buforowanie tutaj, co jest po prostu niemożliwe z konstruktorem. Jednak nie jest to wymagane. Ale ponieważ istnieje możliwość implementacji, która wykonuje buforowanie, ta metoda powinna być preferowana przed używaniem konstruktora.

+4

+1. IMHO, kluczowe jest to, że OP pisze o "* rzeczywistym kodzie", ale to, co dostarcza, to tylko * jedna * implementacja. Inne implementacje mogą istnieć i istnieją dla innych platform. (W szczególności, nie zdziwiłbym się, gdyby dostrzegłem różnicę w implementacji oprogramowania układowego). – ruakh

+0

@ruakh Byłbym przekonany, że alternatywna implementacja będzie pochodzić z alternatywnym javadoc. Kod i javadoc idą w parze, to nie powinien być dokument specyfikacji wysokiego poziomu. To nie pasowałoby do kodu. –

+7

Jawadok java. * Classes * to * specyfikacje, ponieważ inni to dostawcy inni niż Oracle, którzy piszą implementacje Javy i muszą zapewniać tę samą funkcjonalność dla wszystkich tych klas. –

2

Metody te istnieją w każdym typie liczbowym w celu wspierania buforowania. W rzeczywistości dla Double nie używa żadnej pamięci podręcznej, ale dla Integer i Long.

12

Z Javy 1.5+, JVM/JIT gwarantuje buforowanie od Integer s -127 do 127. Dlatego właśnie dla Integer preferowanym podejściem jest użycie valueOf. Powinieneś ogólnie używać valueOf do używania konstruktora dla double, ponieważ wtedy JIT jest w stanie zoptymalizować twój kod według własnego uznania.Na przykład, rozważmy następującą pętlę:

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

w tym przypadku, JIT może precalculate podwójnego obiekt i przypisać tę samą wartość w każdej iteracji pętli, natomiast jeśli były w użyciu new Double(0.0); nie byłby w stanie aby to zrobić.

+0

+1 dla wyróżnienia użycia pamięci podręcznej. – Luke

+2

Gratulacje, masz teraz 2013 powtórzeń, szczęśliwego nowego roku 2013 :) –

+0

@MohamedSakherSawan dzięki - że mój dzień :) – Deco

2

Należy pamiętać, że maszyna JVM została utworzona w celu zmniejszenia rozmiaru kodu dla urządzeń wbudowanych (głównie) - jest to system operacyjny z dekoderem. Pracowałem na kilku wbudowanych platformach Java i na tych "wartość" valueOf byłaby bardziej oczywista, w niektórych przypadkach zaoszczędziłoby to sporo miejsca.

Głównie metoda istnieje, ponieważ "nowy" nie może nigdy używać instancji buforowanych. valueOf MOŻE być zaimplementowany do korzystania z buforowanych instancji (w przeciwnym razie zawsze używałbyś nowych) i prawdopodobnie robi to wszędzie, gdzie oszczędza czas.

Jeśli oni (lub ty) zastąpili tę metodę tą, która faktycznie zrobiła wartości pamięci podręcznej, to cały twój kod zyskałby przewagę tej zmiany, ale bez przygotowania przez podanie metody takiej jak "valueOf", to nigdy by się nie wydarzyło (dobrze, praktycznie nigdy - można zmodyfikować wykonawcę kompilatora/kodu bajtowego, aby mieć "nowe" wartości zwrócone w pamięci podręcznej, ale myślę, że mogłoby to złamać niektóre umowy)

Tak więc pamięć podręczna nie jest tak naprawdę kłamstwem, tylko stanem umysłu.

+2

Czy możesz podać odniesienie do oświadczenia o przyczynie jvm?Metody valueOf są nowe, aby wspierać autoboxing. Nigdy nie powinno być konstruktorów dla tych, w szczególności dotyczy to Boolean. – stolsvik

Powiązane problemy