Czy aby na pewno? ;-)
Spróbujmy sprawdzić jakiej odpowiedzi udzieli nam Java.
Użyjemy takiego kodu:
public class Integers {
public static void main(String[] args) throws Exception{
Integer i1 = 1;
Integer i2 = 1;
System.out.println(i1+"+"+i2+"="+(Integer)(i1+i2));
}
}
Jak łatwo się domyśleć ujrzymy na ekranie taki wynik:
1+1=2
A co gdy kod zmienimy w taki sposób jak poniżej?
import java.lang.reflect.Field;
public class Integers {
public static void main(String[] args) throws Exception {
Integer i1 = 1;
Integer i2 = 1;
System.out.println(i1+"+"+i2+"="+(Integer)(i1+i2));
fixIntegers();
System.out.println(i1+"+"+i2+"="+(Integer)(i1+i2));
}
static void fixIntegers() throws Exception {
Class integerClass = Integer.class;
Field value = integerClass.getDeclaredField("value");
value.setAccessible(true);
value.setInt(Integer.valueOf(2), 3);
}
}
Nagle ujrzymy taki oto wynik:
1+1=2
1+1=3
Dlaczego? ;-)
Sekret tkwi w 2 miejscach, pierwsze to metoda
fixIntegers()
która dokonuje niecnej podmiany wartości 2 na 3 dla obiektu typu Integer
reprezentującego liczbę 2. Drugie, nawet ważniejsze to pewna specyfika implementacji Sun'a. Wprowadzając auto- boxin i unboxing stwierdzono, że ze względu na optymalność wykorzystania pamięci i prędkości wykonywania kodu lepiej dla pewnej grupy obiektów typu
Integer
wprowadzić pewien mechanizm oszczędzający tak pamięć jak i takty procesora. W końcu, po co za każdym razem gdy dokonuje się konwersja z typu
int
na Integer
tworzyć całkiem nowy obiekt... szybciej i taniej będzie stworzyć pewien zestaw obiektów Integer
trzymających wartości stosunkowo najczęściej potrzebne. I tak powstała sytuacja w której dla pewnego zakresu liczb w momencie konwersji na Integer
'a zamiast konwersji jest podstawiany stały obiekt. Dla Sun Java [wersja 6 (build 1.6.0_03-b05), ale też dla Java 5] ten zestaw zaczyna się od liczby -128, a kończy na 127].I w tym cały sekret ;-)
Podobne postybeta
Java 8 nadchodzi....
Sekrety klasy String ;-)
Giń konstruktorze! Giń! ;-)
Nieoczywiste oczywistości ;-) podstępny autoboxing ;-)
Sztuczki tropiciela błędów, part 3 - hackujemy klasy finalne ;-)
Dorzucę swoje dwa grosze :) Jeśli chodzi o ten feature Integerów... to nie tylko Integer ma taki feature... polecam lekture Java Language Specification rozdział 5.1.7
OdpowiedzUsuń