Классы обёртки (Wrapper type) Упаковка и распаковка (boxing unboxing)
Я немного запутался, помогите пожалуйста. Вот к примеру код:
Integer n1 = 1;
Integer n2 = 1;
Integer n3 = new Integer(1);
Integer n4 = new Integer(1);
// 1й вывод
System.out.println(n1 == 1); //true
// 2й вывод
System.out.println(n1 == n2); //true
// 3й вывод
System.out.println(n1 == n3); //false
// 4й вывод
System.out.println(n3 == 1); //true
// 5й вывод
System.out.println(n3 == n4); //false
Переменные n1 и n2 содержат в себе адрес указывающий на память в кэше.
Переменные n3 и n4 содержат в себе адрес указывающий на память в куче.
В 1-м выводе, в переменном n1 выполняется unboxing и возвращается значение, то есть сравнения int == int
Во 2-м выводе, сравниваются две ссылки, указывающие на одну и ту же ячейку в кэш памяти, а то есть, сравнения ref == ref
В 3-м выводе, сравниваются адреса с разных мест, n1 память в кэше, n3 память в куче, а то есть ref == ref
В 4-м выводе как и в 1-м, происходит сравнений значений, после того как выполнится unboxing и вместо адреса в переменном n3 появится значения, а то есть int == int
И в 5-м выводе, произайдёт сравнения адресов которые указаны на разные ячейки памяти в куче ref == ref
Правильно ли, я всё понял?
Ответы (1 шт):
Да, всё верно.
Небольшое дополнение по поводу кэша. Он ограничен, по умолчанию: -128..127.
Это означает
Integer n1 = 127;
Integer n2 = 127;
Integer n3 = 128;
Integer n4 = 128;
// true - ссылка одинаковая из кэша, объект с этим значением был создан заранее, никакую новую память мы не выделили. Взяли готовую ссылку.
System.out.println(n1 == n2);
// false - ссылки разные, в кэш не попали, сделали 2 объекта.
System.out.println(n3 == n4);
Его можно расширить через флаги JVM.
-Djava.lang.Integer.IntegerCache.high=512
или
-XX:AutoBoxCacheMax=512
Тогда кэш будет: -128..512.
Забавный факт -128 значение захардкожено. Исправлять не стали.