Коротка відповідь
Ключовий момент:
==
між двома посилальними типами завжди є порівняльне посилання
- Найчастіше, наприклад, з
Integer
і String
, ви хочете використовувати equals
замість цього
==
між посилальним типом і числовим примітивним типом завжди відбувається числове порівняння
- Тип посилання буде підданий розпаковуванню
- Розпакування
null
завжди кидаєNullPointerException
- Хоча Java має багато спеціальних методів лікування
String
, насправді це НЕ примітивний тип
Наведені вище твердження справедливі для будь-якого даного дійсного коду Java. З таким розумінням у фрагменті, який ви подали, немає жодної суперечливості.
Довга відповідь
Ось відповідні розділи JLS:
Якщо операнди оператора рівності мають як посилальний тип, так і нульовий тип, то ця операція є рівністю об’єкта.
Це пояснює наступне:
Integer i = null;
String str = null;
if (i == null) {
}
if (str == null) {
}
if (str == "0") {
}
Обидва операнди є еталонними типами, і тому ==
порівняння рівності посилань.
Це також пояснює наступне:
System.out.println(new Integer(0) == new Integer(0));
System.out.println("X" == "x".toUpperCase());
Щоб ==
бути числовою рівністю, принаймні один з операндів повинен мати числовий тип :
Якщо операнди операції рівності є як числового типу, або один з числових типів і іншій конвертованій для числового типу, двоичная числове розширення виконується над операндами. Якщо рекламований тип операндів - int
або long
, то виконується перевірка цілої рівності; якщо рекламований тип float or
подвійний`, то виконується перевірка рівності з плаваючою комою.
Зверніть увагу, що двійкове числове просування виконує перетворення набору значень та розпаковування.
Це пояснює:
Integer i = null;
if (i == 0) {
}
Ось уривок із Ефективної другої версії Java, Пункт 49: Віддайте перевагу примітивам, ніж коробкам :
Підводячи підсумок, використовуйте примітиви на відміну від примітивів у коробці, коли у вас є вибір. Первісні типи простіші та швидші. Якщо вам потрібно використовувати примітиви в коробці, будьте обережні! Автобокс зменшує багатослівність, але не небезпеку використання примітивних примітивів. Коли ваша програма порівнює два примітиві в коробці з ==
оператором, вона виконує порівняння ідентичності, що майже напевно не те, що ви хочете. Коли ваша програма виконує обчислення змішаного типу із залученням примітивів в коробці та без коробки, вона робить розпакування, а коли програма розпаковує, вона може кинути NullPointerException
. Нарешті, коли ваша програма встановлює примітивні значення, це може призвести до дорогих і непотрібних створення об’єктів.
Є місця, де вам не залишається іншого вибору, крім як використовувати коробкові примітиви, наприклад, загальні препарати, але в іншому випадку вам слід серйозно подумати, чи рішення щодо використання боксових примітивів виправдане.
Список літератури
Пов’язані запитання
Пов’язані запитання