2013-08-30 20 views
14

Niedawno potknął kod gdzie ludzie piszą takie rzeczyDlaczego warto używać Long.valueOf (...) zamiast długiego literału?

Long myLong = Long.valueOf(42); 

// instead of 

Long myLong = 42L; 

nie mam pojęcia, dlaczego należałoby to zrobić, z wyjątkiem gustu odnośnie czytelności.

Czy brakuje mi czegoś?

+15

Prawdopodobnie dlatego, że nie są świadomi składni "42L". –

+1

Może autor nie wiedział o długich literałach. – Henry

+0

kiedy używasz "Długiej", co się dzieje, przechodzisz przez instynkty "Obiektów", więc masz tendencję do używania metod, plus to samo, co @MagnusGrindalBakken, ja sam nigdy tego nie próbowałem: P –

Odpowiedz

12

z bezpośrednim zadaniem, którego potrzebujesz rzutowania, jeśli przypisanie int do Long (int do domyślnego long jest niejawne) i et autoboxed automatycznie za pomocą Long.valueOf

Long myLong1 = Long.valueOf(42); 
    Long myLong2 = Long.valueOf(42L); 
    Long myLong3 = 42L; 
    Long myLong4 = (long) 42; 

inaczej wszystkie są takie same Zobacz kodu bajtowego wyjście z 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   

Jednak stosując new Long(42L) należy unikać, jeśli nie jest to absolutnie konieczne i jeden z powyższego stwierdzenia należy stosować na rzecz tego jako valueOf metody zwykle buforują zakres wartości (FlyWeight Design Pattern) przez JVM wewnętrznie

Ciekawostki: W przypadku liczb całkowitych & Oracle JVM zasięg może być sterowane za pomocą -XX:AutoBoxCacheMax=

+1

@chrylis tak nie kupuj auto boxingu. spróbuj 'Long myLong4 = 42;' –

1

valueOf pobiera prymitywne long. W przypadku literałów zgadzam się, że 42L jest lepszy, ale jeśli masz zmienną int lub , Long.valueOf to dobry sposób na uzyskanie Long. valueOf używa także pamięci podręcznej o wartości od -128 do 127, co daje jej niewielką przewagę wydajności nad wartościami wspólnymi dla new Long(long).

+0

Możesz także użyć przypisania z prymitywnymi długimi zmiennymi. Powinno być wciąż takie samo ('Long myLong = myPrimitiveLong;) – Puce

+0

@Puce hm, dobry punkt. Ale nadal może być użyteczne, gdy chcesz wywołać metody instancji na 'Long', np.' Long.valueOf (myPrimitive) .compareTo (otherPrimitive) '; lub z jakiegoś innego powodu chcesz 'Long' bez konieczności przypisywania go do prymitywu. –

2

są równoważne kompilator budowy samego bajtowego zarówno

+1

Jesteś tego pewien? –

+2

@DavidWallace yes Proszę zobaczyć wyjście 'javap' w mojej odpowiedzi. –

3

urywek

Long myLong = 42L; 

jest wewnętrznie samo jak

Long myLong = Long.valueOf(42); 

kompilator wytworzenia tej samej bajtowego.

1

Ludzie, którzy nie zdają sobie sprawy, że możesz to zrobić w inny sposób?

Zastanawiam się, czy kompilator jest wystarczająco inteligentny, aby przekonwertować wartość Long.valueOf na ten sam kod bajtowy w przypadku stałych połączeń. W przeciwnym razie wystąpiłby drobny uderzenie wydajnościowe (nie znaczące, ale można zauważyć, że jest to mocno obciążone, zwarte pętle).

Wersja valueOf jest przydatna do odlewania wartości prymitywne bezpiecznie, poręczny, jeśli robisz kilka odlewów między prymitywnych typów i nie chce (na przykład) stwarzają problemy robi: (int) longBiggerThanIntCanHandle

(Nie zależy Ci na wykonywaniu (długich) intValue, ale jeśli robisz kilka konwersji w obie strony, dobrze jest użyć valueOf jako konwencji, dla bezpieczeństwa.)

-3

As Long.Metoda valueOf może przynieść znacznie lepszą wydajność w przestrzeni i czasie poprzez buforowanie często żądanych wartości. Long.valueOf caches -128 do 127 wartości i te wartości mogą być ponownie użyte.

W przypadku przypisania nowy obiekt zostanie utworzony za każdym razem.

Metoda valueOf zachowuje się inaczej w przypadku tylko typu String.

+0

Zobacz odpowiedź Prashanta Bhate'a – Puce

2

Myślę też, że to przypomnienie o java przed java5, gdzie nie było autoboxing i gdzie

Long l = 42L; 

nie może zostać skompilowany.

+0

Ale przed Java5 nie było wartości valueOf (long) :) – Durandal

+0

w rzeczy samej: http://docs.oracle.com/javase/6/docs/api/ java/lang/Long.html # valueOf (long) – chburd

Powiązane problemy