Зачем использовать Long.valueOf(...), а не длинный литерал?
Недавно я наткнулся на код, где люди пишут такие вещи, как
Long myLong = Long.valueOf(42);
// instead of
Long myLong = 42L;
Я не знаю, зачем это делать, кроме личного вкуса относительно удобочитаемости.
Я что-то пропустил?
Ответы
Ответ 1
с прямым назначением, которое требуется выполнить, если присвоение int
to Long
(int
для примитива Long
неявно), и они автоматически получают autoboxed
, используя Long.valueOf
Long myLong1 = Long.valueOf(42);
Long myLong2 = Long.valueOf(42L);
Long myLong3 = 42L;
Long myLong4 = (long) 42;
в противном случае они все одинаковы. См. вывод bytecode из javap
public static void main(java.lang.String[]);
Code:
0: ldc2_w #16 // long 42l
3: invokestatic #18 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
6: astore_1
7: ldc2_w #16 // long 42l
10: invokestatic #18 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
13: astore_2
14: ldc2_w #16 // long 42l
17: invokestatic #18 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
20: astore_3
21: ldc2_w #16 // long 42l
24: invokestatic #18 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
27: astore 4
29: return
Однако использование new Long(42L)
следует избегать, если это не является абсолютно необходимым, и один из вышеуказанных операторов должен использоваться в пользу этого, поскольку методы valueOf
обычно кэшируют диапазон значений (FlyWeight Design Pattern
) с помощью JVM внутри
Общая информация: в случае целых чисел и JVM Oracle диапазон можно контролировать с помощью -XX:AutoBoxCacheMax=
Ответ 2
Отрывок
Long myLong = 42L;
внутренне совпадает с
Long myLong = Long.valueOf(42);
Компилятор будет генерировать один и тот же байт-код.
Ответ 3
Они эквивалентны, компилятор построит один и тот же байт-код для обоих
Ответ 4
Я также думаю, что это напоминание о java перед java5, где не было автобоксинга, и где
Long l = 42L;
не удалось скомпилировать.
Ответ 5
valueOf
принимает примитив long
. Для литералов я бы согласился, что 42L
лучше, но если у вас есть переменная int
или long
, Long.valueOf
- хороший способ получить long
. valueOf
также использует кеш значений от -128 до 127, что дает ему небольшое преимущество производительности над new Long(long)
для общих значений.
Ответ 6
Люди, которые не понимают, что вы можете сделать это по-другому?
Мне нужно задаться вопросом, достаточно ли достаточно компилятора преобразовать Long.valueOf в тот же байт-код для постоянных вызовов. В противном случае было бы небольшое поражение производительности (неважно, но вы можете заметить, что он сильно запущен, плотные петли).
Версия valueOf полезна для безопасного приведения примитивных значений, удобна, если вы делаете кучу отливок между примитивными типами и не хотите (например) вызывать проблемы:
(Целое) longBiggerThanIntCanHandle
(Вам не нужно делать (long) intValue, но если вы делаете кучу конверсий в обоих направлениях, полезно использовать valueOf в качестве соглашения для безопасности.)
Ответ 7
Как метод Long.valueOf, вероятно, даст значительно лучшую производительность пространства и времени, кэшируя часто запрашиваемые значения.
Long.valueOf кеширует от -128 до 127 значений, и эти значения могут быть повторно использованы.
В случае назначения новый объект будет создан каждый раз.
Метод valueOf ведет себя по-разному в случае только String.