Следует ли избегать автоматической упаковки в Java?

#java #autoboxing

#java #автоматическая упаковка

Вопрос:

Бывают случаи, когда метод ожидает примитивный тип double , и вы передаете Double объект в качестве параметра.

Поскольку компилятор распаковывает переданный объект, увеличит ли это использование памяти или снизит производительность?

Ответ №1:

Это то, что Java Notes говорит об автоматической упаковке:

Предпочитайте примитивные типы

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

  1. Примитивные типы могут быть намного быстрее, чем соответствующие типы оболочек, и никогда не медленнее.
  2. Неизменность (не может быть изменена после создания) типов оболочек может сделать их использование невозможным.
  3. Может возникнуть некоторое неожиданное поведение, включающее == (сравнение ссылок) и .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, который ожидает a double , но вы обрабатываете значение как Double между ними, то вы делаете бесполезную автоматическую упаковку.

  • автоматическая распаковка может привести NullPointerException к тому, что вы этого не ожидаете:

     public void frobnicate(Double d) {
      double result = d / 2;
      // ...
    }
      
  • использование коллекций автоматически упакованных значений использует намного больше памяти, чем сопоставимый double[] , например.

Ответ №4:

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

Ответ №5:

Следует избегать автоматической упаковки. Это может привести к ошибкам из-за перегрузки и оказывает некоторое влияние на производительность. Тем не менее, это может не быть проблемой в вашем приложении. Но помните о последствиях.

Комментарии:

1. ссылка больше не действительна.