Почему в javadoc Double.valueOf указано, что значения кэшируются, если это не так?
В OpenJDK для метода:
public static Double valueOf(double d)
в документации написано:
Возвращает экземпляр Double, представляющий указанное значение типа double. Если новый экземпляр Double не требуется, этот метод следует обычно использовать вместо конструктора Double(double), так как данный метод, вероятно, обеспечит значительно лучшую производительность по времени и памяти за счет кэширования часто запрашиваемых значений.
Однако вот фактический код:
public static Double valueOf(double d) {
return new Double(d);
}
Кэш оказывается ложью! Что здесь происходит?
5 ответ(ов)
Метод существует для многих типов: Integer
, Long
, BigDecimal
и других, и документация всегда одинакова: при определённых обстоятельствах (которые не определены) метод может вернуть одно и то же значение.
Насколько мне известно, кэширование реализовано только для целочисленных типов, и оно возвращает кэшированные экземпляры для значений в диапазоне от -128 до 127 (самых распространённых значений). Для BigDecimal
кэш в настоящее время работает для значений от 0 до 10.
В более поздних версиях Java может быть расширено это поведение для других значений и типов. Поэтому использовать этот код сегодня - это разумно, так как это может сделать ваш код быстрее в будущем (при этом код не станет медленнее сегодня).
Например, компилятор Java использует этот API при генерации кода для автопаковки.
С документацией API все в порядке:
Этот метод вероятно приведет к...
Это значит, что реализация может использовать кэширование в этом случае, что просто невозможно с помощью конструктора. Однако, это не является обязательным. Тем не менее, поскольку существует вероятность того, что у вас есть реализация, которая действительно использует кэширование, предпочтительнее использовать этот метод вместо конструктора.
Начиная с Java 1.5 и выше, JVM/JIT гарантирует кэширование объектов Integer
в диапазоне от -127 до 127. Именно поэтому предпочтительным подходом для работы с Integer
является использование метода valueOf
. Аналогично, рекомендуется использовать valueOf
для Double
, так как это позволяет JIT оптимизировать ваш код более эффективно.
Рассмотрим следующий пример цикла:
for (Object o: objectList) {
o.setValue(Double.valueOf(0.0));
}
В этом случае JIT может предвычислить объект Double
и переопределить одно и то же значение на каждой итерации цикла. Если же вы используете new Double(0.0);
, JIT не сможет этого сделать, так как каждый раз будет создаваться новый объект. Это может привести к дополнительным затратам по памяти и времени выполнения. Поэтому, всегда старайтесь использовать метод valueOf
, когда это возможно.
Дизайнеры API, вероятно, не хотели ограничивать возможность альтернативной реализации. Теперь разработчики могут свободно добавлять кэширование в класс Double
.
Методы valueOf()
существуют для каждого числового типа с целью поддержки кэширования. На самом деле, для типа Double
кэширование не используется, в то время как для типов Integer
и Long
применяется механизм кэширования.
Как сослаться на метод в Javadoc?
Пример кода с несколькими строками в комментарии Javadoc
Как сослаться на другой метод того же класса в Javadoc?
JavaDoc: где добавлять заметки/пояснения в документацию?
Инициализация ArrayList в одну строчку