2011-12-19 7 views
52

En OpenJDK, para el método:¿Por qué Double.valueof javadoc dice que almacena valores en caché, cuando no?

public static Double valueOf(double d) 

el Javadoc dice:

devuelve una instancia de doble representa el valor doble especificado. Si no se requiere una nueva instancia doble, este método generalmente se debe usar con preferencia al constructor Doble (doble), ya que es probable que este método produzca un mejor rendimiento de espacio y tiempo al almacenar en caché los valores frecuentemente solicitados.

Aquí está el código real:

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

La memoria caché es una mentira! ¿Que está pasando aqui?

+31

La documentación siempre es incorrecta. Recuerda eso. –

+5

¿De dónde saca el código de todos modos? OpenJDK6? OpenJDK7? Apache Harmony? GNU Classpath? – scravy

+0

@scravy Estoy viendo OpenJDK7 pero este código no ha cambiado durante años en los lanzamientos oficiales de Sun. –

Respuesta

54

El método existe para muchos tipos: Integer, Long, BigDecimal y otros, y la documentación es siempre el mismo: En algunas circunstancias (que no están definidos), el método puede devolver el mismo resultado.

AFAIK, el almacenamiento en caché solo se implementa para tipos enteros y devuelve instancias en caché para valores entre -128 y 127 (valores más comunes). Para BigDecimal, la memoria caché funciona actualmente para los valores de 0 a 10.

Las versiones posteriores de Java pueden extender este comportamiento a otros valores/más tipos. Por lo tanto, es inteligente usar este código hoy porque puede hacer que su código sea más rápido mañana (y el código no será más lento hoy en día).

El compilador de Java, por ejemplo, usa esta API al generar código para el autoboxing.

6

Los diseñadores de la API probablemente no quisieron restringir la implementación alternativa. Esos ahora son libres de agregar almacenamiento en caché a la clase Double.

29

No hay nada malo con la documentación del API:

Este método es probable para producir ...

Es decir, se permite que una aplicación de almacenamiento en caché de hacer aquí, que es simplemente no es posible con un constructor. Sin embargo, no es obligatorio. Pero, dado que es probable que tenga una implementación que realiza el almacenamiento en caché, este método debe preferirse a usar un constructor.

+4

+1. En mi humilde opinión, el punto clave es que el OP escribe "* el * código real", pero lo que suministra es solo * una * implementación. Otras implementaciones pueden existir y existen para otras plataformas. (En particular, no me sorprendería ver una diferencia aquí en una implementación de firmware.) – ruakh

+0

@ruakh Hubiera pensado que una implementación alternativa también vendría con javadoc alternativo. El código y javadoc van juntos, no se supone que sea un documento de especificación de alto nivel. Eso no pertenecería con el código. –

+7

Las clases javadoc of the java. * * Son * especificaciones, ya que otras son proveedores distintos de Oracle que escriben implementaciones Java y tienen que proporcionar la misma funcionalidad para todas estas clases. –

2

Estos métodos valueOf() existen en todos los tipos numéricos con el fin de admitir el almacenamiento en caché. De hecho, para Double no usa ningún caché, excepto para Integer y Long.

12

Desde Java 1.5+, JVM/JIT garantiza el almacenamiento en memoria caché de Integer s -127 a 127. Por eso, para Integer el enfoque preferido es usar valueOf. Por lo general, debe usar valueOf usando el constructor para double porque entonces el JIT puede optimizar su código como lo considere conveniente.Por ejemplo, considere el siguiente bucle:

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

En este caso, el JIT puede precalcular el doble objeto y volver a asignar el mismo valor en cada iteración del bucle, mientras que si se va a utilizar new Double(0.0); no sería capaz Para hacer eso.

+0

+1 para resaltar un caso de uso del almacenamiento en caché. – Luke

+2

Felicitaciones, ahora tiene representantes de 2013, feliz año nuevo 2013 :) –

+0

@MohamedSakherSawan gracias - eso hizo mi día :) – Deco

2

Recuerde que la JVM se creó para reducir el tamaño del código para dispositivos integrados (principalmente): es un sistema operativo de decodificador. He trabajado en algunas plataformas java incrustadas y en ellas el valor de "valor de" sería más obvio, en algunos casos ahorraría bastante espacio.

Principalmente, el método existe porque "nuevo" no puede usar instancias en caché. valueOf PUEDE implementarse para usar instancias almacenadas en caché (de lo contrario, siempre usaría nuevas) y probablemente lo haga donde sea que se demuestre para ahorrar tiempo.

Si ellos (o usted) reemplazaron ese método por uno que en realidad tenía valores de caché, entonces todo su código obtendría la ventaja de ese cambio, pero sin prepararse proporcionando un método como "valueOf" nunca podría suceder (bueno, prácticamente nunca - podrías modificar el compilador/bytecode executor para tener "nuevos" valores de caché de retorno, pero creo que eso rompería algunos contratos)

Así que el caché no es realmente una mentira, solo un estado de ánimo.

+2

¿Puede dar una referencia a la declaración sobre el motivo de la jvm?Los métodos valueOf son nuevos, para admitir el autoboxing. Nunca debería haber habido constructores para estos, esto en particular va para Boolean. – stolsvik

Cuestiones relacionadas