#java #autoboxing
#java #автоматическая упаковка
Вопрос:
Бывают случаи, когда метод ожидает примитивный тип double
, и вы передаете Double
объект в качестве параметра.
Поскольку компилятор распаковывает переданный объект, увеличит ли это использование памяти или снизит производительность?
Ответ №1:
Это то, что Java Notes говорит об автоматической упаковке:
Предпочитайте примитивные типы
Используйте примитивные типы там, где нет необходимости в объектах по двум причинам.
- Примитивные типы могут быть намного быстрее, чем соответствующие типы оболочек, и никогда не медленнее.
- Неизменность (не может быть изменена после создания) типов оболочек может сделать их использование невозможным.
- Может возникнуть некоторое неожиданное поведение, включающее == (сравнение ссылок) и .equals() (сравнение значений). Смотрите Ссылку ниже для примеров.
Комментарии:
1. Специфическое неожиданное поведение включает исключения NullPointerExceptions при распаковке.
2. сюрпризы автоматической упаковки: theserverside.com/news/thread.tss?thread_id=27129
3. да, но вопрос был о «автоматической упаковке». Если он спросит: «Должен ли я использовать примитивы над классами-оболочками», то, конечно, вы правы, в противном случае сама автоматическая упаковка не влияет на производительность современных JVM — по крайней мере, из того, что я знаю.
4. @Kris: Он спрашивает, следует ли избегать автоматической упаковки, на что я ответил «Предпочитаю примитивные типы». На его замечание о «тяжести» я ответил своим первым пунктом.
5. @0A0D: снова верно, но вы все еще говорите о тяжести классов-оболочек по сравнению с примитивами, а не о тяжести самой автоматической упаковки 🙂
Ответ №2:
Эмпирическое правило таково: всегда используйте примитивы, если это возможно.
Бывают случаи, когда это невозможно, например, коллекции, поэтому используйте обертки только тогда.
Ответ №3:
Это выбор дизайна, а не тривиальный ответ для каждого случая.
Есть несколько пунктов, которые могут повлиять на ваше решение:
Преимущества:
-
Автоматическая упаковка и автоматическая распаковка могут облегчить чтение вашего кода:
Исключение всего ненужного
.doubleValue()
иDouble.valueOf()
уменьшает визуальный шум и может облегчить чтение вашего кода. -
Автоматическая упаковка позволяет легко использовать коллекции примитивных значений (например, a
List<Double>
, …)
Недостатки:
-
чрезмерная, ненужная автоматическая упаковка и автоматическая распаковка могут снизить производительность.
Например, если у вас есть API, который возвращает a
double
, и другой API, который ожидает adouble
, но вы обрабатываете значение как Double между ними, то вы делаете бесполезную автоматическую упаковку. -
автоматическая распаковка может привести
NullPointerException
к тому, что вы этого не ожидаете:public void frobnicate(Double d) { double result = d / 2; // ... }
-
использование коллекций автоматически упакованных значений использует намного больше памяти, чем сопоставимый
double[]
, например.
Ответ №4:
Вам не нужно избегать автоматической упаковки, если речь идет о производительности, JVM должна справиться с этим. Единственное, что вам следует учитывать, это читаемость вашего кода.
Ответ №5:
Следует избегать автоматической упаковки. Это может привести к ошибкам из-за перегрузки и оказывает некоторое влияние на производительность. Тем не менее, это может не быть проблемой в вашем приложении. Но помните о последствиях.
Комментарии:
1. ссылка больше не действительна.