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 doublevalor passado para instanciar o BigDecimalobjeto. Em outras palavras: o valor do BigDecimalobjeto será o que você vê ao fazer System.out.println(d).
Se você usar new BigDecimal(d), no entanto, o BigDecimaltentará representar o doublevalor 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 BigDecimalque é 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. newvai sempre instanciar um novo valor, mesmo que não seja necessário (melhor exemplo: new Boolean(true)vs. Boolean.valueOf(true)).