Я нашел два способа получить объект BigDecimal из двойного d.
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
Что было бы лучше? Будет ли valueOf создавать новый объект?
В общем (не только BigDecimal) что рекомендуется - new или valueOf?
Спасибо.
java
bigdecimal
Маниш Мулани
источник
источник
Ответы:
Это два отдельных вопроса: «Для чего мне использовать
BigDecimal
?» и "Что мне вообще делать?"For
BigDecimal
: это немного сложно, потому что они не делают то же самое .BigDecimal.valueOf(double)
будет использовать каноническоеString
представление оdouble
стоимости передаваемого в экземплярBigDecimal
объекта. Другими словами: ценностьBigDecimal
объекта будет тем, что вы видите, когда делаетеSystem.out.println(d)
.Однако, если вы используете
new BigDecimal(d)
, тоBigDecimal
будет пытаться представитьdouble
значение как можно точнее . Это обычно приводит к хранению гораздо большего количества цифр, чем вы хотите. Строго говоря, это более правильноvalueOf()
, но намного менее интуитивно понятно.В JavaDoc есть хорошее объяснение этого:
В общем, если результат такой же (то есть не в случае
BigDecimal
, а в большинстве других случаев), тоvalueOf()
следует предпочесть: он может выполнять кэширование общих значений (как показано наInteger.valueOf()
) и даже изменять поведение кеширования без необходимо изменить вызывающего абонента. всегдаnew
будет создавать новое значение, даже если в этом нет необходимости (лучший пример: vs. ).new Boolean(true)
Boolean.valueOf(true)
источник
new BigDecimal()
лучшеBigDecimal.valueOf()
?new BigDecimal()
будет предпочтительнее, и пример того, когдаBigDecimal.valueOf()
предпочтительнее?new BigDecimal(1.0/30.0);
иBigDecimal.valueOf(1.0/30.0)
. Посмотрите, какой результат на самом деле ближе к числовой дроби 1/30.Если вы используете свои
BigDecimal
объекты для хранения валютных ценностей, я настоятельно рекомендую НЕ в своих расчетах какие-либо двойные значения.Как указано в другом ответе, существуют известные проблемы с точностью с двойными значениями, и они снова будут вас преследовать.
Как только вы справитесь с этим, ответ на ваш вопрос будет прост. Всегда используйте метод конструктора со значением String в качестве аргумента конструктора, так как
valueOf
дляString
.Если вам нужны доказательства, попробуйте следующее:
Вы получите следующий результат:
См. Также этот связанный вопрос
источник
В основном valueOf (double val) просто делает это:
return new BigDecimal(Double.toString(val));
Поэтому -> да, будет создан новый объект :).
В общем, я думаю, это зависит от вашего стиля кодирования. Я бы не стал смешивать valueOf и new, если оба результата имеют одинаковый результат.
источник
valueOf()
имеет более интуитивное поведение, аnew BigDecimal(d)
более правильное . Попробуйте оба варианта и увидите разницу.new BigDecimal(1) != new BigDecimal(1)
ноBigDecimal.valueOf(1) == BigDecimal.valueOf(1)
BigDecimal
неизменен следует относиться так же, как примитивные обертки (Integer
,Byte
, ...) иString
трактуются: идентификатор объекта должен не имеет значения в код, только значение должно иметь значение.valueOf()
должно быть предпочтительнее. Но обратите внимание, что это не кеширует (и, вероятно, оно того не стоит).BigDecimal.valueOf(double)