Encontré dos formas de sacar el objeto BigDecimal de una doble d.
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
¿Cuál sería un mejor enfoque? ¿ValueOf crearía un nuevo objeto?
En general (no solo BigDecimal), ¿qué se recomienda: nuevo o valueOf?
Gracias.
java
bigdecimal
Manish Mulani
fuente
fuente
Respuestas:
Esas son dos preguntas separadas: "¿Para qué debo usar
BigDecimal
?" y "¿Qué hago en general?"Para
BigDecimal
: esto es un poco complicado, porque no hacen lo mismo .BigDecimal.valueOf(double)
utilizará la representación canónicaString
deldouble
valor pasado para instanciar elBigDecimal
objeto. En otras palabras: el valor delBigDecimal
objeto será lo que vea cuando lo hagaSystem.out.println(d)
.new BigDecimal(d)
Sin embargo, si utiliza ,BigDecimal
intentará representar eldouble
valor con la mayor precisión posible . Esto generalmente dará como resultado que se almacenen muchos más dígitos de los que desea. Estrictamente hablando, es más correcto quevalueOf()
, pero es mucho menos intuitivo.Hay una buena explicación de esto en JavaDoc:
En general, si el resultado es el mismo (es decir, no en el caso de
BigDecimal
, pero en la mayoría de los otros casos), entoncesvalueOf()
debería preferirse: puede realizar el almacenamiento en caché de valores comunes (como se ve enInteger.valueOf()
) e incluso puede cambiar el comportamiento de almacenamiento en caché sin la persona que llama debe cambiarse. siemprenew
creará una instancia de un nuevo valor, incluso si no es necesario (mejor ejemplo: vs. ).new Boolean(true)
Boolean.valueOf(true)
fuente
new BigDecimal()
mejor queBigDecimal.valueOf()
?new BigDecimal()
sería preferible y un ejemplo de cuándoBigDecimal.valueOf()
sería preferible?new BigDecimal(1.0/30.0);
yBigDecimal.valueOf(1.0/30.0)
. Vea qué resultado está realmente más cerca de la fracción numérica 1/30.Si está utilizando sus
BigDecimal
objetos para almacenar valores de moneda, le recomiendo encarecidamente que NO incluya valores dobles en ningún lugar de sus cálculos.Como se indica en otra respuesta, existen problemas de precisión conocidos con valores dobles y estos volverán a atormentarlo a lo grande.
Una vez que supere eso, la respuesta a su pregunta es simple. Utilice siempre el método del constructor con el valor String como argumento del constructor, ya que no hay ningún
valueOf
método paraString
.Si desea una prueba, intente lo siguiente:
Obtendrá el siguiente resultado:
Vea también esta pregunta relacionada
fuente
Básicamente valueOf (double val) solo hace esto:
return new BigDecimal(Double.toString(val));
Por lo tanto -> sí, se creará un nuevo objeto :).
En general, creo que depende de su estilo de codificación. No mezclaría valueOf y "new", si ambos son el mismo resultado.
fuente
valueOf()
tiene el comportamiento más intuitivo , mientras quenew BigDecimal(d)
tiene el más correcto . Pruebe ambos y vea la diferencia.new BigDecimal(1) != new BigDecimal(1)
peroBigDecimal.valueOf(1) == BigDecimal.valueOf(1)
BigDecimal
es inmutable debe ser tratado de la misma manera que los envoltorios primitivos (Integer
,Byte
, ...) yString
son tratados: la identidad del objeto no debe importar a su código, sólo el valor debería importar.valueOf()
debería generalmente ser preferidos. Pero tenga en cuenta queBigDecimal.valueOf(double)
no hace ningún almacenamiento en caché (y probablemente tampoco valdría la pena).