Когда я должен использовать примитивы вместо обертывания объектов?
-
04-07-2019 - |
Вопрос
На самом деле здесь Это похожая тема с небольшой практической ценностью.
Насколько я понимаю, примитивы работают лучше и должны использоваться везде, кроме случаев, когда требуются функции, связанные с объектами (например, проверка null
). Правильно?
Решение
Не забывайте, что, поскольку создание новой оболочки для каждого вхождения в бокс довольно дорого, особенно учитывая, что она обычно используется в одной области действия метода, Автобокс использует пул распространенных оболочек.
На самом деле это реализация шаблон дизайна для облегченного веса . Когда для общеизвестного значения происходит упаковка, вместо создания нового экземпляра оболочки, предварительно созданный экземпляр выбирается из пула и возвращается.
Одним из следствий этого является то, что все еще не рекомендуется использовать автобокс для научных расчетов . Например, код d = a * b + c использует классы Integer для a, b, c и d, а сгенерированный код - d.valueOf (a.intValue () * b.intValue () + c.intValue ( )). Все эти вызовы методов имеют свои накладные расходы, поэтому обычно рекомендуется использовать автобокс при необходимости для хранения примитивов в коллекциях .
И даже в этом случае, если у вас есть огромная коллекция с целочисленной упаковкой int, накладные расходы могут означать более длительное время выполнения, до 20 раз больше , как сообщается в этой статье .
<Ч>Jb добавляет этот важный комментарий:
Также Wrapper.valueOf (примитив) использует пул оберток. Поэтому предпочитайте Integer.valueOf (5) новому Integer (5)
Другие советы
Примитивы быстрее, когда они используются , так как объекты должны быть распакованы перед использованием; таким образом, существует дополнительный шаг для виртуальной машины. Например, чтобы выполнить арифметику с целым числом, его необходимо сначала преобразовать в целое число, прежде чем можно будет выполнить арифметику.
Во многих бизнес-приложениях это, вероятно, редко имеет значение. Но если вы писали что-то очень тяжелое, например, процессор графических преобразований, вас это гораздо больше интересует.
да, примитивы быстрее объектов. Начиная с Java 5 вы можете даже смешивать примитивы и объекты, не конвертируя их вручную. Механизм автобокса позаботится только об этом.
это означает, что если вы поместите примитив в коллекцию, компилятор не будет жаловаться и неявно преобразует примитив в объект.
Если вам нужно хранить примитивы в коллекциях, вы можете использовать commons-primitives .
Я предпочитаю использовать примитивы оберткам, единственное место, где абсолютно необходимы обертки, это классы сущностей. Базы данных поддерживают нули, поэтому сущности тоже должны. Р>
Однажды я работал над проектом, который использовал примитивы (и доморощенный ORM) для доступа к базе данных:
class Foo{
int xxx = -1;
...
}
А потом у вас было:
void persist(Foo foo){
...
statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX());
...
}
Боже, это было зло. Р>
Я бы сказал, что вам следует беспокоиться об использовании примитивов над оболочками только тогда, когда вы профилируете свое приложение и видите, что автобокс является проблемой производительности или памяти. По моему опыту, проблема памяти перед циклами процессора становится проблемой, когда речь идет о примитивах и оберточных объектах.