Od wersji Java 1.5 w wielu sytuacjach można w dużym stopniu wymieniać Integer
z int
.Java: Integer jest równy vs. ==
Jednak znalazłem potencjalną wadę w moim kodzie, która mnie trochę zaskoczyła.
Poniższy kod:
Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
mismatch = true;
wydawało się być nieprawidłowo ustalone niedopasowanie, gdy wartości były równe, chociaż nie mogę określić, w jakich okolicznościach. Ustawiłem punkt przerwania w Eclipse i zauważyłem, że wartości Integer
są zarówno 137, jak i sprawdziłem wyrażenie boolowskie i powiedziałem, że jest to fałsz, ale kiedy przekroczyłem to ustawienie było niezgodne z ustawieniem true.
Zmiana warunkowy do:
if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))
rozwiązaniu problemu.
Czy ktoś może rzucić trochę światła na to, dlaczego tak się stało? Do tej pory widziałem tylko zachowanie na moim localhost na moim własnym komputerze. W tym konkretnym przypadku kod zakończył pomyślnie około 20 porównań, ale zakończył się niepowodzeniem. Problem był powtarzalny.
Jeśli jest to powszechny problem, powinien powodować błędy w innych naszych środowiskach (dev i test), ale jak dotąd nikt nie zgłosił problemu po setkach testów wykonujących ten fragment kodu.
Czy nadal nie jest uzasadnione korzystanie z ==
do porównywania dwóch wartości Integer
?
Oprócz wszystkich dokładnych odpowiedzi poniżej, poniższy link Stackoverflow ma sporo dodatkowych informacji. To rzeczywiście byłby odpowiedział na moje pierwotne pytanie, ale ponieważ nie wspominając autoboxing na moje pytanie, to nie pojawi się w wybranych sugestii:
Why can't the compiler/JVM just make autoboxing “just work”?
Dzięki, to z pewnością wyjaśnia, dlaczego 137 zawodzi! Odpowiada również na moje pytanie o to, dlaczego nie jest to powszechny problem, w 95% przypadków, w których napotkam, wartość będzie mniejsza niż 127. Dobrze jest teraz to złapać, ale za 5% tam, gdzie nie jest. –
Interesująca notatka: aż do kilku tygodni temu, cdiCt i cdsCt były zarówno intami, więc to było w porządku, ale musiałem zrobić ich Integers w celu sprawdzenia sytuacji zerowej, która jest obsługiwana inaczej ... –
@Jeremy Tak, jest to dość niejasny problem, ale z reguły używasz .equals() dla Objects i == dla prymitywów. Nie możesz polegać na autounboxingu w testach równości. – Adam