2008-10-27 4 views
14

Фактически here - аналогичная тема, мало практическая. Насколько я понимаю, примитивы работают лучше и должны использоваться повсюду, кроме случаев, когда необходимы объекты, связанные с объектами (например, null). Правильно?Когда я должен использовать примитивы вместо обертывания объектов?

ответ

23

Не забывайте, что, поскольку создание новой обертки для каждого случая бокса является довольно дорогостоящим, особенно учитывая, что он обычно используется в одной области метода, Autoboxing использует пул общих оберток.

Это фактически реализация flyweight design pattern. Когда бокс происходит для общеизвестного значения, вместо создания нового экземпляра оболочки, предварительно созданный экземпляр извлекается из пула и возвращается.

Одним из последствий является: до сих пор не рекомендуется использовать автобоксинг для научных расчетов. Например, код d = a * b + c использует классы Integer для a, b, c и d, а сгенерированный код - d.valueOf (a.intValue() * b.intValue() + c.intValue ()). Все эти вызовы методов имеют свои собственные накладные расходы, поэтому обычно рекомендуется использовать автобоксинг при необходимости для хранения примитивов в коллекциях.

И даже тогда, если у вас есть огромная коллекция целых оберточной междунар, накладные расходы могут предполагает более длительное время выполнения, до 20 раз больше как reported in this article.


Jb добавляет этот важный комментарий:

Рекомендуем также Wrapper.valueOf (примитивный) использует пул оберток. Поэтому предпочтите Integer.valueOf (5) на новый Integer (5)

5

Да, примитивы быстрее объектов. С помощью java 5 вы можете смешивать примитивы и объекты без ручной конвертации друг в друга. Механизм автобоксинга заботится только об этом.

это означает, что если вы поместите примитив в коллекцию, компилятор не будет жаловаться и не будет преобразовывать примитив в объект неявно.

+0

В каких случаях они быстрее? прохождение ссылок вокруг так же быстро, как прохождение примитивов вокруг. – 2008-10-27 11:05:42

+1

возьмите int, например. Целое число - это объект, содержащий одно целое поле. Целое число намного больше, чем int. Это похоже на поле Fedex, которое содержит int. – nkr1pt 2008-10-27 11:09:16

10

Примитивы быстрее, если они использовали, так как объекты должны быть распакованы перед использованием; таким образом, для выполнения виртуальной машины есть дополнительный шаг. Например, чтобы выполнить арифметику в Integer, она должна быть сначала преобразована в int до того, как будет выполнена арифметика.

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

1

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

+1

Я не согласен. Зачем ждать, пока производительность станет проблемой, когда вы сможете написать эффективный код в первую очередь? В 9 раз из 10 вам не нужны дополнительные функциональные возможности, предлагаемые классом-оболочкой, поэтому зачем их использовать? – alexmcchessers 2008-10-27 11:39:03

1

Если вам нужно хранить примитивы в коллекциях, вы можете использовать commons-primitives.

Я предпочитаю использовать примитивы для оберток, только место, которое обязательно должно иметь оболочки, - это классы сущностей. Базы данных поддерживают нули, поэтому сущности тоже должны.

я когда-то работал над проектом, который использовал примитивы (и доморощенного ОРМ) в доступе к базе данных:

class Foo{ 
    int xxx = -1; 
... 
} 

А потом было:

void persist(Foo foo){ 
    ... 
    statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX()); 
    ... 
} 

Бог это зло.

Смежные вопросы