2012-01-27 9 views
21

Recenlty Widziałem kodu (Java) tak:Różnice pomiędzy nowym Integer (123), Integer.valueOf (123) i tylko 123

myMethod(new Integer(123)); 

Jestem obecnie Refaktoryzacja kodu, a tam jest wskazówka w narzędzie sonar, że to jest bardziej przyjazny w użyciu pamięć czegoś takiego:

myMethod(Integer.valueOf(123)); 

jednak w tym przypadku, myślę, że nie ma różnicy, czy chciałbym używać:

myMethod(123); 

Mogłabym to zrozumieć, gdybym przekazał zmienną do metody, ale na sztywno zakodowane int? Lub jeśli byłby długi/podwójny itp. I chcę Długiej reprezentacji liczby. Ale liczba całkowita?

+4

W rzeczywistości nie ma znaczenia, czy robisz "myMethod (Integer.valueOf (123))" lub "myMethod (123)", ponieważ autoboxing użyje dla ciebie 'Integer.valueOf()'. osądź sam, który z nich jest bardziej czytelny. (zakładając, że "myMethod' bierze" Integer') – soulcheck

Odpowiedz

27

new Integer(123) utworzy nową instancję Object dla każdego połączenia.

Według javadoc, Integer.valueOf(123) ma różnicy buforuje obiekty ... więc może (lub nie może) skończyć z tym samym Object jeśli nazywają go więcej niż raz.

Na przykład, następujący kod:

public static void main(String[] args) { 

     Integer a = new Integer(1); 
     Integer b = new Integer(1); 

     System.out.println("a==b? " + (a==b)); 

     Integer c = Integer.valueOf(1); 
     Integer d = Integer.valueOf(1); 

     System.out.println("c==d? " + (c==d)); 

    } 

ma następujący wynik:

a==b? false 
c==d? true 

co do korzystania z wartości int, używasz prymitywny typ (biorąc pod uwagę metoda wykorzystuje również typ pierwotny na sygnaturze) - będzie zużywał nieco mniej pamięci i może być szybszy, ale nie będzie można na przykład dodać go do kolekcji.

Zobacz także kod Java AutoBoxing, jeśli podpis metody korzysta z Integer - podczas korzystania z niego JVM automatycznie wybierze dla ciebie numer Integer.valueOf() (dlatego też używa pamięci podręcznej).

+1

Czy zatem autoboxing zawsze tworzy nowy obiekt? Czy może również skorzystać z buforowania? Jeśli dodasz te informacje do swojego posta, myślę, że twoja będzie najlepszą odpowiedzią. –

+0

@Marcelo ... czy możesz podać te informacje, które sugerował Alex D ... –

+1

@MananShah już tam jest (: Tak - autoboxing używa 'Integer.valueOf()', więc używa buforowania. – Marcelo

5

public static Integer valueOf(int i)

Zwraca instancję całkowitą reprezentującą określoną wartość int. Jeśli nowa instancja Integer nie jest wymagana, ta metoda powinna być używana jako na ogół w stosunku do konstruktora Integer (int), jako ta metoda może przynieść znacznie lepszą wydajność w zakresie czasu i przestrzeni, poprzez buforowanie często żądanych wartości.

Parametry:
i - wartość int.
Powraca:
a Integer instance reprezentujący i.
od:
1,5

odnoszą http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#valueOf%28int%29

Ten wariant valueOf dodano w JDK 5 do Byte, Short, Integer i Long (to już istniała w błahej sprawy Boolean od JDK 1.4). Wszystkie te są, oczywiście, obiektami niezmiennymi w Javie.Kiedyś, jeśli potrzebujesz obiektu Integer z int, możesz skonstruować nową liczbę całkowitą. Ale w JDK 5+, powinieneś naprawdę użyć valueOf, ponieważ Integer teraz buforuje obiekty Integer między -128 a 127 i może przekazać ci ten sam dokładny obiekt Integer (0) za każdym razem zamiast marnować konstrukcję obiektu na zupełnie nową identyczną liczbę całkowitą obiekt.

private static class IntegerCache { 
private IntegerCache(){} 

static final Integer cache[] = new Integer[-(-128) + 127 + 1]; 

static { 
    for(int i = 0; i < cache.length; i++) 
    cache[i] = new Integer(i - 128); 
} 
} 

public static Integer valueOf(int i) { 
final int offset = 128; 
if (i >= -128 && i <= 127) { // must cache 
    return IntegerCache.cache[i + offset]; 
} 
    return new Integer(i); 
} 

odnoszą Why YOU should use Integer.valueOf(int)

EDIT

autoboxing i utworzenie obiektu:

Ważnym punktem musimy wziąć pod uwagę to, że autoboxing nie zmniejsza tworzenie obiektów, ale zmniejsza kod złożoność. Dobrą zasadą jest użycie typów pierwotnych, w których obiekty nie są potrzebne, z dwóch powodów:

Rodzaje prymitywów nie będą wolniejsze niż ich odpowiednie typy opakowań i mogą być znacznie szybsze. Może wystąpić pewne nieoczekiwane zachowanie obejmujące := (porównaj odniesienia) i .equals() (porównaj wartości).

Zwykle, gdy typy pierwotne są podzielone na typy opakowań, JVM przydziela pamięć i tworzy nowy obiekt. Ale w niektórych szczególnych przypadkach JVM wykorzystuje ten sam obiekt.

Poniższa lista prymitywów przechowywane jako niezmiennych obiektów:

  • wartości logiczne prawdziwych i fałszywych

  • Wszystko bajt wartości

  • krótkie wartości od -128 do 127

  • wartości int od -128 do 127

  • znak w zakres \ u0000 do \ u007F

patrz http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance_issue

1

int pierwotnych, a nie obiektów.

new Integer(123) i Integer.valueOf(123) zwracają Integer obiekt reprezentujący wartość 123. za javadoc do Integer.valueOf():

Zwraca wystąpienie całkowitą reprezentującą określoną wartość int. Jeśli nowa instancja Integer nie jest wymagana, ta metoda powinna ogólnie być używana zamiast konstruktora Integer (int), ponieważ ta metoda może zapewnić znacznie lepszą wydajność w przestrzeni i czasie poprzez buforowanie często żądanych wartości .

1

Czy twoja metoda wymaga modelu int lub Integer?

new Integer(int) i Integer.valueOf(int) zarówno powrócić Integer obiektów, ale valueOf powinny być preferowane, ponieważ jest bardziej efektywne, ponieważ zwraca pamięci podręcznej obiektów. Jeśli twoja metoda wymaga Integer, powinieneś użyć Integer.valueOf.

Jeśli twoja metoda wymaga numeru int, użyj numeru int (np. 123).

Jednak nie jest to bezwzględnie konieczne, aby dopasować typy w ten sposób z powodu autoboxing, który automatycznie konwertuje int do Integer i odwrotnie, gdy typy nie pasują. To pozwala ci przekazać int w metodę wymagającą Integer i Integer w metodę wymagającą int. Ale pamiętaj, że są pewne koszty związane z autoboxingiem. Najczęstszym przykładem użycia autoboxingu jest przechowywanie prymitywów w kolekcji.

1

tylko zakres od -128 do +127 narzędzi w pamięci podręcznej.

Integer a = new Integer(1); 
Integer b = new Integer(1); 

System.out.println("a==b? " + (a==b)); 

Integer c = Integer.valueOf(127); 
Integer d = Integer.valueOf(127); 

System.out.println("c==d? " + (c==d)); 

Integer e = Integer.valueOf(128); 
Integer f = Integer.valueOf(128); 

System.out.println("e==f? " + (e==f)); 

Patrz tej specyfikacji Java:

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7

w JDK 5+, naprawdę powinieneś używać valueOf ponieważ Integer teraz buforuje obiekty całkowitą z przedziału od -128 do 127, a może pod ręką cię dokładnie taki sam Obiekt Integer (0) za każdym razem zamiast marnować konstrukcję obiektu na zupełnie nowy identyczny obiekt Integer.

Powiązane problemy