BigDecimal-использовать new или valueOf


я столкнулся с двумя способами получения BigDecimal объекта из двойного d.

1. new BigDecimal(d)
2. BigDecimal.valueOf(d)

какой подход был бы лучше? Бы стоимость создания нового объекта?

В общем (не только BigDecimal), что рекомендуется - new или valueOf?

спасибо.

3 67

3 ответа:

это два отдельных вопроса: "Что я должен использовать BigDecimal?"и "что мне делать вообще?"

на BigDecimal: Это немного сложно, потому что они не делай то же самое. BigDecimal.valueOf(double) использовать canonical String представление на double значение, переданное для создания экземпляра , потом BigDecimal попытается представить double стоимостью как можно более точно. Это будет обычно результат в гораздо больше цифр хранятся, чем вы хотите. Строго говоря, это более правильно, чем valueOf(), но это гораздо менее интуитивно.

есть хорошее объяснение этого в JavaDoc:

результаты этого конструктора можно несколько непредсказуемо. Можно предположить, что писать!--12--> в Java создает BigDecimal который точно равен 0.1 (значение без шкалы 1, со шкалой 1), но на самом деле он равен 0.1000000000000000055511151231257827021181583404541015625. Это связано с тем, что 0.1 не может быть представлен точно как double (или, если на то пошло, как двоичная дробь из любой конечной длины). Таким образом, значение, которое передается в конструктор, не точно равно 0.1, внешний вид несмотря на.

в общем, если результат тот же (т. е. не в случае BigDecimal, но и в большинстве других случаев), то valueOf() должно быть предпочтительным: он может делать кэширование общих значений (как видно на Integer.valueOf()) и он может даже изменить поведение кэширования без необходимости изменения вызывающего абонента. new будет всегда создать экземпляр нового значения, даже если это не обязательно (лучший пример:new Boolean(true) и Boolean.valueOf(true)).

если вы используете BigDecimal объекты для хранения значений валют, то я настоятельно рекомендую вам сделать не включить любые двойные значения в любом месте в своих расчетах.

как указано в другом ответе, есть известные проблемы точности с двойными значениями, и они вернутся, чтобы преследовать вас большое время.

как только вы пройдете мимо этого, ответ на ваш вопрос прост. Всегда используйте метод конструктора со строковым значением в качестве аргумента конструктор, как нет valueOf метод String.

если вы хотите доказательств, попробуйте следующее:

BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);

вы получите следующий результат:

bd1 = 0.01000000000000000020816681711721685132943093776702880859375
bd2 = 0.01

см. также вопрос

в основном valueOf (double val) просто делает это:

return new BigDecimal(Double.toString(val));

поэтому - > да, будет создан новый объект :).

В общем, я думаю, это зависит от вашего стиля кодирования. Я бы не смешивал valueOf и" новый", если оба результата одинаковы.