Krótka odpowiedź
Kluczowa kwestia jest taka:
==
między dwoma typami odwołań jest zawsze porównaniem referencyjnym
- Najczęściej, np. Z
Integer
i String
, equals
zamiast tego chciałbyś użyć
==
między typem referencyjnym a liczbowym typem pierwotnym jest zawsze porównanie liczbowe
- Typ referencyjny zostanie poddany konwersji podczas rozpakowywania
- Unboxing
null
zawsze rzucaNullPointerException
- Chociaż Java ma wiele specjalnych metod leczenia
String
, w rzeczywistości NIE jest to typ prymitywny
Powyższe instrukcje dotyczą dowolnego poprawnego kodu Java. Z tym zrozumieniem nie ma żadnych niespójności w przedstawionym fragmencie.
Długa odpowiedź
Oto odpowiednie sekcje JLS:
Jeśli operandy operatora równości są typu referencyjnego lub typu null , operacja jest równa obiektowi.
To wyjaśnia następujące kwestie:
Integer i = null;
String str = null;
if (i == null) {
}
if (str == null) {
}
if (str == "0") {
}
Oba operandy są typami referencyjnymi i dlatego ==
jest porównaniem równości odwołań.
To wyjaśnia również następujące kwestie:
System.out.println(new Integer(0) == new Integer(0));
System.out.println("X" == "x".toUpperCase());
Aby ==
być równością liczbową, co najmniej jeden z argumentów musi być typu liczbowego :
Jeśli oba operandy operatora równości są typu liczbowego lub jeden jest typu liczbowego, a drugi można konwertować na typ liczbowy, na operandach jest wykonywana binarna promocja liczbowa. Jeśli promowanym typem operandów jest int
lub long
, wykonywany jest test równości liczb całkowitych; jeśli promowany typ to float or
double`, to wykonywany jest zmiennoprzecinkowy test równości.
Zwróć uwagę, że binarna promocja liczbowa wykonuje konwersję zestawu wartości i konwersję po rozpakowaniu.
To wyjaśnia:
Integer i = null;
if (i == 0) {
}
Oto fragment z Effective Java 2nd Edition, pozycja 49: Preferuj prymitywy od pudełkowych :
Podsumowując, zawsze używaj prymitywów zamiast prymitywów pudełkowych, kiedy tylko masz wybór. Typy prymitywne są prostsze i szybsze. Jeśli musisz używać prymitywów w pudełkach, bądź ostrożny! Autoboxing redukuje gadatliwość, ale nie ogranicza niebezpieczeństwa używania pudełkowych prymitywów. Kiedy twój program porównuje dwa prymitywy w pudełku z ==
operatorem, dokonuje porównania tożsamości, co prawie na pewno nie jest tym, czego chcesz. Kiedy twój program wykonuje obliczenia typu mieszanego z udziałem prymitywów zapakowanych i nieopakowanych, robi to rozpakowywanie, a kiedy program wykonuje rozpakowywanie, może rzucać NullPointerException
. Wreszcie, gdy program zawiera prymitywne wartości, może to spowodować kosztowne i niepotrzebne tworzenie obiektów.
Są miejsca, w których nie masz innego wyboru, jak tylko użyć prymitywów pudełkowych, np. Generycznych, ale w przeciwnym razie powinieneś poważnie rozważyć, czy decyzja o użyciu prymitywów pudełkowych jest uzasadniona.
Bibliografia
Powiązane pytania
Powiązane pytania