На самом деле здесь аналогичная тема с небольшой практической ценностью. Насколько я понимаю, примитивы работают лучше и должны использоваться везде, за исключением случаев, когда необходимы функции, связанные с объектами (например, проверка null
). Верно?
Когда следует использовать примитивы вместо объектов-оболочек?
Ответы (5)
Не забывайте, что, поскольку создание новой оболочки для каждого экземпляра бокса обходится довольно дорого, особенно если учесть, что она обычно используется в одной области действия метода, Автоупаковка использует пул общих оболочек.
На самом деле это реализация легковесный шаблон дизайна. Когда для общеизвестного значения происходит упаковка, вместо создания нового экземпляра оболочки предварительно созданный экземпляр извлекается из пула и возвращается.
Одно из следствий: по-прежнему не рекомендуется использовать автоупаковку для научных расчетов. Например, код d = a * b + c использует классы Integer для a, b, c и d, а сгенерированный код имеет вид d.valueOf(a.intValue() * b.intValue() + c.intValue( )). У всех этих вызовов методов есть свои накладные расходы, поэтому обычно рекомендуется использовать автоупаковку, когда это необходимо для хранения примитивов в коллекциях.
И даже в этом случае, если у вас есть огромная коллекция целочисленных оберток int, накладные расходы могут привести к более длительному времени выполнения, вплоть до в 20 раз, поскольку сообщается в этой статье.
Jb добавляет важный комментарий:
Также Wrapper.valueOf(primitive) использует пул оберток. Так что предпочитайте 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());
...
}
Боже это было зло.
Я бы сказал, что вам следует беспокоиться об использовании примитивов вместо оболочек только тогда, когда вы профилируете свое приложение и видите, что автоупаковка является проблемой производительности или памяти. По моему опыту, память становится проблемой до циклов ЦП, когда речь идет о примитивах и объектах-оболочках.