BigDecimal является расширяемым и не имеет конструктора копирования. Это угроза безопасности?

Согласно пункту 24 действующего Java (создание защитных копий при необходимости) изменяемые объекты представляют угрозу безопасности, особенно когда они передаются в качестве аргументов конструктора. Рекомендуется делать защитные копии по мере необходимости.

BigDecimal должен быть неизменным, но не окончательным. Согласно пункту 15 "Эффективная Java" (минимизировать изменчивость), класс не может быть неизменным, если он не является окончательным или все его конструкторы не являются расширяемыми.

Усугублять проблему, BigDecimal не предоставляет конструктор копирования.

Ну действуй BigDecimal аргументы представляют угрозу безопасности? Нужно ли пройти через болезненный процесс вызова new BigDecimal(untrusted.toString())?

2 ответа

Решение

Согласно /questions/40947805/pochemu-klass-java-bigdecimal-ne-obyavlen-kak-finalnyij/40947815#40947815:

Как обсуждалось в статье "Эффективная Java", пункт 13, "Неизменность в пользу фаворита", это был недосмотр дизайна, когда был написан

Согласно /questions/5962739/neizmennyij-klass-dolzhen-byit-okonchatelnyim/5962751#5962751 BigDecimal создает угрозу безопасности, и защитные копии должны быть сделаны по мере необходимости.

Похоже, самый быстрый способ создать защитную копию:

public static BigDecimal copyOf(BigDecimal value)
{
    if (value == null || value.getClass() == BigDecimal.class)
        return value;
    return new BigDecimal(value.unscaledValue(), value.scale());
}

ОБНОВЛЕНИЕ: По-видимому, теперь это явно обсуждается в Effective Java 3rd edition, Item 17 (Minimum Mutable).

Что-то вроде этого тоже может сработать:

BigDecimal newValue = oldValue == null ? null : oldValue.add(BigDecimal.ZERO);.

Другие вопросы по тегам