2013-10-02 11 views
5

Mam pytanie o wywiadzie:(Java core)

public Integer v1 = 127; 
public Integer v2 = 127; 
public Integer v3 = 513; 
public Integer v4 = 513; 

public void operatorEquals(){ 
    if (v1==v2) 
     System.out.println("v1 == v2"); 
    else throw new RuntimeException("v1 != v2"); 
    if (v3==v4) 
     System.out.println("v3 == v4"); 
    else throw new RuntimeException("v3 != v4"); 
} 

**Result**: java.lang.RuntimeException: **v3 != v4** 

można wyjaśnić: dlaczego? Nie mam żadnych sugestii.

Odpowiedz

10

Java Integer obiekty są buforowane do 127, ale nie powyżej.

Efekt ten jest bardzo podobny do tego, jak String interning prace, więc wszystko Integer obiektów o wartościach w przedziale [-128; 127] są takie same przypadki też - wracając z prawdą referencyjna sprawdzania równości zbyt (np. ==), nie tylko przy użyciu .equals().

EDIT z Arnaud Denoyelle

Od Integer.java:

public static Integer valueOf(int i) { 
    assert IntegerCache.high >= 127; 
    if (i >= IntegerCache.low && i <= IntegerCache.high) 
     return IntegerCache.cache[i + (-IntegerCache.low)]; 
    return new Integer(i); 
} 
+1

Nie będę tego westchnął. –

+4

Czy możesz wyjaśnić bardziej szczegółowe ...? – user2171669

+1

Edytowałem, aby wyświetlić kod "Integer # valueOf()". Jak widać, między IntegerCache.low (-128) a IntegerCache.high (+127), w rzeczywistości nie tworzy się nowej liczby całkowitej. –

4

To jest zdefiniowane zachowanie Java kiedy autoboxing. Sprawdź odpowiedni Java Language Specification section. Przeczytaj także rozdział dyskusyjny. Dodaje się ustęp pochodzi od specyfikacji:

Jeśli wartość p jest zapakowane jest prawdziwe, fałszywe, bajt, lub char w zakres \ u0000 do \ u007f lub numer int lub zwarcie między -128 i 127 (włącznie), a następnie niech r1 i r2 będą wynikami dowolnych dwóch konwersji bokserskich p. Zawsze jest tak, że r1 == r2.

Idealnie, boksowanie danej prymitywnej wartości p, zawsze dałoby identyczne odniesienie . W praktyce może to nie być możliwe przy użyciu istniejących technik implementacji. Powyższe zasady są pragmatycznym kompromisem w postaci . Ostatnia klauzula powyżej wymaga, aby pewne wspólne wartości zawsze były zapakowane w nieodróżnialne obiekty. Implementacja może buforować je, leniwie lub niecierpliwie. W przypadku innych wartości formulacja nie przyjmuje żadnych założeń dotyczących tożsamości pudełkowych wartości w części programatora. Umożliwiłoby to (ale nie wymagało) dzielenie się niektórymi lub wszystkimi tymi odniesieniami.

Zapewnia to, że w większości typowych zachowań będzie to pożądane ustawienie, bez narzucania nadmiernej kary za wydajność, zwłaszcza na małych urządzeniach. Implementacje o mniejszej ilości pamięci mogą, na przykład, dla cache'u buforować wszystkie wartości char i short, a także wartości int i long w zakresie od -32K do + 32K.

Dla int, obiekty między -128 a 127 (włącznie) autoboxed Integer objects zwróci wartość true dla sprawdzenia ==. Mówi się, że te liczby całkowite są buforowane i mają stałą pulę. Ale jeśli po prostu zrobisz new Integer(int) utworzone obiekty będą zawsze inne.