Что лучше: позволить Java делать автобоксинг или использовать valueOf()

Мне просто интересно, есть ли разница в том, что java autobox говорит целое число:

Integer myInteger = 3; // This will call Integer.valueOf()

или иметь свой код как

Integer myInteger = Integer.valueOf(3);

Есть ли какая-то микрооптимизация? Я знаю, что второй более явный, но он также более ненужный, есть ли какая-то разница, кроме этого?


person Oscar Gomez    schedule 09.03.2011    source источник
comment
Прирост производительности? вряд ли, я думаю это просто микрооптимизация.   -  person whirlwin    schedule 10.03.2011
comment
Это правда, только что отредактировал мой вопрос, спасибо.   -  person Oscar Gomez    schedule 10.03.2011


Ответы (3)


Они все равно внутренне равны, поэтому используйте первый вариант. Велика вероятность, что будущие оптимизации компилятора могут сделать первый еще быстрее в будущем.

person Daniel    schedule 09.03.2011
comment
Вполне вероятно, что будущие оптимизации компилятора могут сделать первый еще быстрее в будущем. Это не имеет смысла, если должны быть какие-то встроенные функции, они должны применяться к обоим. - person bestsss; 10.03.2011
comment
Контрпример: они могут решить определить константы для первых 5 чисел, в то время как в настоящее время они используют массив для хранения первых 127 (?) экземпляров. Компилятор может принять решение превратить первое в myInteger = Integer.THREE, в то время как другое по-прежнему является вызовом метода и доступом к массиву. - person Daniel; 10.03.2011
comment
Опять же, это не имеет смысла... Если они добавят ЛЮБЫЕ константы, это не будет иметь никакого значения для JIT. - person bestsss; 10.03.2011
comment
Преобразование выполняет не JIT, а javac! JIT делает и другие приятные вещи. - person Daniel; 10.03.2011
comment
Разница в том, что код выполняется не javac, а скомпилированный код JIT. - person bestsss; 10.03.2011
comment
bestsss: Это компилятор, который превращает, например. Объединение строк с вызовами StringBuilder. Просто потому, что в инструкциях байт-кода не определена конкатенация строк. Также в инструкциях байт-кода не определено автоматическое упаковывание. Это работа компилятора, а не работа во время выполнения. Компилятор распознает, что для получения рабочего байт-кода из исходного кода требуется автоупаковка. И компилятор может делать это как угодно, лишь бы он соответствовал спецификации. Когда это сделано, байт-коду больше не нужно знать, была ли автоупаковка или ручная упаковка с явным вызовом valueOf. - person Daniel; 10.03.2011
comment
@Daniel, вы так долго объясняете, как javac может сделать программу быстрее ... давайте посмотрим, как ICONST_X байтовые коды получают константы, определенные в каком-то классе (скажем, Integer), который сам по себе гарантирует, что код не будет работать с более старой java; однако изменение JIT (в этой более новой Java) гарантирует, что даже более старый код, не скомпилированный с такой крутой новой функцией, будет работать точно так же... и это может произойти вместо этого, не загрязняя код w /бесполезные константы. Я закончил обсуждение, оно становится просто бессмысленным - person bestsss; 10.03.2011
comment
Есть причина, по которой старый код, созданный с помощью StringBuffers (для скорости), больше не работает быстро по сравнению с кодом, который также мог быть создан с помощью конкатенации строк. Потому что они переработали Java, и теперь прежний более медленный, но более читаемый код стал волшебным образом быстрее! Извините, я не мог объяснить это лучше, чтобы вы могли понять это. - person Daniel; 10.03.2011
comment
вау, это никогда не кончается. concat всегда был быстрее, чем StringBuffer/Builder. - person bestsss; 10.03.2011
comment
@bestsss Я бы не согласился с вами в последней части. Предполагая, что a и b являются строками, String s = a + b; будет переведено компилятором в String s = new StringBuilder(a).append(b).toString(); На самом деле, пункт 51 Эффективной Java называется Остерегайтесь выполнения кокатенации строк по причине ... Цитата, "The moral is simple: don't use the string concatenation operator to combine more than a few strings unless perfromance is irrelevant." - person corsiKa; 11.03.2011
comment
String s = new StringBuilder(a).append(b).toString(); на самом деле это new StringBuilder(Stingg.valueOf(a))... Я никогда не имел в виду оператор +, но String.concat для двух строк String.concat() всегда был самым быстрым способом. (примечание: я очень, очень хорошо знаю, как stringBuffer/builder и строка внедряются внутри, в свое время даже у нас был AsyncStringBuffer, который фактически копировал строки, в отличие от StringBuffer, который, как правило, вызывал некоторые утечки и фрагментацию) (отредактируйте: если не ясно: String.concat лучше всего подходит только для 2 и 2 строк, для большего количества других методов лучше) - person bestsss; 11.03.2011
comment
Привет, bestsss: я просто хотел дать (возможно, но маловероятно) то, как JVM, компилятор и библиотеки могут измениться в будущем таким образом, что Integer a = 3 больше не равен Integer.valueOf(3). В своем маловероятном, но возможном примере я хотел привести пример, как может выглядеть такое изменение. И я все же считаю, что здесь играет роль компилятор, а не только JIT, который вы отрицали, если я правильно вас понял. - person Daniel; 11.03.2011

Я бы использовал первый вариант. То же самое с меньшим количеством кода.

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

Таким образом, единственная причина не использовать автобоксинг — это его недоступность.

person Goran Jovic    schedule 09.03.2011
comment
В более старой версии JVM в любом случае не было автоупаковки, поэтому это не скомпилировалось. Начиная с 1.5, где стал доступен автобокс, варианты одинаковые. - person Daniel; 10.03.2011
comment
@Daniel: Да, это хорошая сторона. Вы знаете, если это не работает сразу после компиляции (или не работает). - person Goran Jovic; 10.03.2011

Я знаю, что на самом деле нет большой разницы в производительности, см. этот пост здесь. На самом деле разницы нет, но вы должны использовать valueOf, потому что Integer теперь кэширует объекты Integer между -128 и 127.

person 7dr3am7    schedule 09.03.2011
comment
Почему только для операций на стороне сервера? На клиенте работает одинаково. - person Daniel; 10.03.2011
comment
Я просто предположил, что он / она занимается разработкой на стороне сервера (веб-сайт веб-приложения), для этого в основном используется java :) - person 7dr3am7; 10.03.2011
comment
Исправлено :) надеюсь, что это было хорошо для вас. - person Daniel; 10.03.2011