poniedziałek, października 19, 2020

Nieoczywiste oczywistości ;-) podstępny autoboxing ;-)

Java jest prostym językiem, ale dodawanie kolejnych ficzerów powoduje, że staje się coraz bardziej skomplikowana.

Jakoś tak milion lat temu w Java 5 dodano autoboxing i auto unboxing. I to bardzo ułatwia życie, tak naprawdę mało kto teraz pamięta w trakcie kodowanie, że int i Integer to dwie różne rzeczy i zwykle po prostu ludzie pamiętają, że Integer to taki "specjalny" int który można trzymać w kolekcjach.

I stąd są problemy....

Bo co się stanie w sytuacji gdy z mapy albo listy pobieramy Integer'y i porównujemy je z czymś przy pomocy ==?

To zależy czy to z czym porównujemy to int czy Integer ;-)
Jeśli int to kompilator w trakcie kompilacji zrobi nam auto unboxing naszego pobranego Integer'a.
Jeśli Integer to zależy.... gdy to jest Integer w zakresie -128..127 to zwykle powinno działać == tak jakby zadziałało equals.... przy założeniu, że oba te Integer'y zostały poprawnie "stworzone", czyli nie przez new Integer(int).
Jeśli coś wyższego niż 127, albo niższego niż -128 to raczej nie zadziała == jak equals.

Niby to wszystko to żaden problem, ale.....

Idźmy dalej, a co jak mamy takie 2 z overloadowane metody:

boolean test() {
return isEven(10);
}

boolean isEven(int x) {
return x%2==0;
}

boolean isEven(Integer x) {
return x%2==0;
}

To która zostanie zawołana gdy wykona się metoda test? ;-)

Wiadomo, że isEven(int), ale jeśli usuniemy metodę isEven(int) to kod nadal się będzie kompilował i nadal będzie działał ;-)

Tu niby problem nie jest z autoboxingiem i unboxingime chociaż trochę jest ;-) bo jak kompilator decyduje którą metodę zawołać? No szuka metody najbardziej "szczegółowej". 

Czyli tutaj w metodzie test ma 10, a 10 to int, więc wie, że ma zawołać isEven(int), ale jeśli nie będzie metody isEven(int) to popatrzy i znajdzie metodę isEven(Integer) więc dokona auto boxingu tego 10 do Integer.valueOf(10) i wrzuci je do tej metody...
Jakby nie było tej metody, ale byłaby metoda isEven(Object) to ona by została zawołana....

To niby są wszystko oczywistości, ale takie nie do końca oczywiste ;-)

A patrząc jak ludzie chętnie dodają do API nowe metody to takie problemy się po prostu muszą zdarzać ;-)






Podobne postybeta
Człowiek się uczy całe życie - źle rozumiałem cache'owanie Integerów :-)
Ile to jest 1+1 w Java'ie?
Magia w Java'ie ;-)
finalize() - do czego służy, a do czego nie i z czym to się je.
Sztuczki tropiciela błędów - breakpoint na sterydach ;-)

Brak komentarzy:

Publikowanie komentarza