Essas são duas perguntas distintas: "O que devo usar BigDecimal
?" e "O que eu faço em geral?"
Pois BigDecimal
: isso é um pouco complicado, porque eles não fazem a mesma coisa . BigDecimal.valueOf(double)
usará a representação canônicaString
do double
valor passado para instanciar o BigDecimal
objeto. Em outras palavras: o valor do BigDecimal
objeto será o que você vê ao fazer System.out.println(d)
.
Se você usar new BigDecimal(d)
, no entanto, o BigDecimal
tentará representar o double
valor com a maior precisão possível . Isso geralmente resultará em muito mais dígitos armazenados do que você deseja. A rigor, é mais correto do que valueOf()
, mas é muito menos intuitivo.
Há uma boa explicação disso no JavaDoc:
Os resultados desse construtor podem ser um tanto imprevisíveis. Pode-se supor que a gravação new BigDecimal(0.1)
em Java cria um BigDecimal
que é exatamente igual a 0,1 (um valor fora de escala de 1, com uma escala de 1), mas na verdade é igual a 0,1000000000000000055511151231257827021181583404541015625. Isso ocorre porque 0,1 não pode ser representado exatamente como um double
(ou, nesse caso, como uma fração binária de qualquer comprimento finito). Portanto, o valor que está sendo passado para o construtor não é exatamente igual a 0,1, apesar das aparências.
Em geral, se o resultado for o mesmo (ou seja, não no caso de BigDecimal
, mas na maioria dos outros casos), então valueOf()
deve ser preferido: ele pode fazer o cache de valores comuns (como visto em Integer.valueOf()
) e pode até mesmo alterar o comportamento do cache sem o chamador deve ser alterado. new
vai sempre instanciar um novo valor, mesmo que não seja necessário (melhor exemplo: new Boolean(true)
vs. Boolean.valueOf(true)
).