Когда я должен использовать примитивы вместо обертывания объектов?

StackOverflow https://stackoverflow.com/questions/239560

Вопрос

На самом деле здесь Это похожая тема с небольшой практической ценностью. Насколько я понимаю, примитивы работают лучше и должны использоваться везде, кроме случаев, когда требуются функции, связанные с объектами (например, проверка 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());
     ...
}

Боже, это было зло.

Я бы сказал, что вам следует беспокоиться об использовании примитивов над оболочками только тогда, когда вы профилируете свое приложение и видите, что автобокс является проблемой производительности или памяти. По моему опыту, проблема памяти перед циклами процессора становится проблемой, когда речь идет о примитивах и оберточных объектах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top