Me deparei com duas maneiras de obter um objeto BigDecimal de um d duplo.
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
Qual seria a melhor abordagem? ValueOf criaria um novo objeto?
Em geral (não apenas BigDecimal), o que é recomendado - new ou valueOf?
Obrigado.
java
bigdecimal
Manish Mulani
fonte
fonte
Respostas:
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
dodouble
valor passado para instanciar oBigDecimal
objeto. Em outras palavras: o valor doBigDecimal
objeto será o que você vê ao fazerSystem.out.println(d)
.Se você usar
new BigDecimal(d)
, no entanto, oBigDecimal
tentará representar odouble
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 quevalueOf()
, mas é muito menos intuitivo.Há uma boa explicação disso no JavaDoc:
Em geral, se o resultado for o mesmo (ou seja, não no caso de
BigDecimal
, mas na maioria dos outros casos), entãovalueOf()
deve ser preferido: ele pode fazer o cache de valores comuns (como visto emInteger.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)
).fonte
new BigDecimal()
melhor do queBigDecimal.valueOf()
?new BigDecimal()
seria preferido e um exemplo de quandoBigDecimal.valueOf()
seria preferido?new BigDecimal(1.0/30.0);
eBigDecimal.valueOf(1.0/30.0)
. Veja qual resultado está realmente mais próximo da fração numérica 1/30.Se você estiver usando seus
BigDecimal
objetos para armazenar valores monetários, então eu recomendo fortemente que você NÃO envolva nenhum valor duplo em seus cálculos.Conforme afirmado em outra resposta, existem problemas de precisão conhecidos com valores duplos e eles voltarão para assombrá-lo.
Depois de superar isso, a resposta à sua pergunta é simples. Sempre use o método do construtor com o valor String como o argumento do construtor, pois não há
valueOf
método paraString
.Se você quiser uma prova, tente o seguinte:
Você obterá a seguinte saída:
Veja também esta questão relacionada
fonte
Basicamente, valueOf (double val) faz apenas isso:
return new BigDecimal(Double.toString(val));
Portanto -> sim, um novo objeto será criado :).
Em geral, acho que depende do seu estilo de codificação. Eu não misturaria valueOf e "new", se ambos fossem o mesmo resultado.
fonte
valueOf()
tem o comportamento mais intuitivo , enquanto onew BigDecimal(d)
tem o mais correto . Experimente os dois e veja a diferença.new BigDecimal(1) != new BigDecimal(1)
masBigDecimal.valueOf(1) == BigDecimal.valueOf(1)
BigDecimal
é imutável deve ser tratada da mesma forma que os wrappers primitivos (Integer
,Byte
...) eString
são tratados: a identidade do objeto deve não importa ao seu código, apenas o valor deve importar.valueOf()
deveria ser preferido. Mas observe que isso não faz nenhum cache (e provavelmente não valeria a pena também).BigDecimal.valueOf(double)