Зачем использовать 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.