[ Pobierz całość w formacie PDF ]

tomatyczne rzutowanie referencji na ich wspólny typ. Wyjaśnia to po-
niższy przykład:
String s = "pewien";
Przykład ten
StringBuffer sb = new StringBuffer("tekst");
pochodzi z piątego
boolean mutable = true;
wydania książki
Java in a Nutshell
CharSequence cs = mutable ? sb : s;
(O Reilly).
W wersjach poprzedzających wersję Tiger podczas kompilacji tego kodu
wystąpił by błąd, ponieważ sb (typu StringBuffer) i s (typu String) nie
mogą być do siebie przypisywane. Ponieważ oba typy implementują in-
terfejs CharSequence, kod ten uda się jednak skompilować, jeśli zastosu-
jemy rzutowanie:
CharSequence cs = mutable ? (CharSequence)sb : (CharSequence)s;
W wersji Tiger można użyć dowolnego wspólnego typu dla obu wyra-
żeń. W tym przypadku CharSequence spełnia to wymaganie i może być
Z punktu widzenia
poprawnym typem wyniku wyrażenia.
technicznego
możliwość ta
Efektem takiego rozwiązania jest to, że każde dwa obiekty zawsze mają
związana jest
wspólny typ java.lang.Object, wobec czego wynik działania operatora
z obsługą
ternarnego na wyrażeniach, które nie są typów podstawowych, może generyczności
w wersji Tiger,
zostać przypisany do obiektu typu java.lang.Object.
ale wydaje mi się,
że lepiej było
wspomnieć o niej
Instrukcje sterujące i rozpakowywanie
w tym miejscu.
Generyczność
W języku Java istnieje kilka instrukcji sterujących, których argumentem została omówiona
szczegółowo
jest wartość typu boolean lub wyrażenie, którego wynik jest typu
w rozdziale 2.
boolean. Fakt, że w instrukcjach tych mogą teraz występować również
obiekty typu Boolean, nie powinien już stanowić zaskoczenia. Dodatkowo
instrukcja wyboru switch akceptuje szereg nowych typów.
Jak to osiągnąć?
Wprowadzona w wersji Tiger możliwość automatycznego rozpakowy-
wania obiektów typu Boolean do wartości typu boolean używana jest
Instrukcje sterujące i rozpakowywanie 97
także w przypadku instrukcji if/else, while i do. Poniższy przykład nie
wymaga szczegółowych objaśnień:
Boolean arriving = false;
Boolean late = true;
Integer peopleInRoom = 0;
int maxCapacity = 100;
boolean timeToLeave = false;
while (peopleInRoom
if (arriving) {
System.out.println("Miło Cię widzieć.");
peopleInRoom++;
} else {
Uruchamiając
peopleInRoom--;
ten przykład,
}
należy pamiętać,
if (timeToLeave) {
że wykonuje on
do {
System.out.printf("Osoba numer %d musi opuścić pokój!%n",
nieskończoną pętlę.
peopleInRoom);
peopleInRoom--;
} while (peopleInRoom > 0);
}
}
W przykładzie tym zachodzi wiele operacji opakowywania i rozpako-
wywania w różnych instrukcjach sterujących. Warto dokładnie przeana-
lizować ich działanie.
Inną instrukcją, która zyskała na wprowadzeniu automatycznego rozpa-
kowywania, jest instrukcja wyboru switch. We wcześniejszych wer-
sjach języka Java akceptowała ona jedynie wartości typów int, short,
char i byte. Oprócz typów wyliczeniowych wprowadzonych w wersji Ti-
Typy wyliczeniowe
ger obsługuje ona dzięki rozpakowywaniu teraz również obiekty typów
omówiłem
Integer, Short, Char i Byte.
w rozdziale 3.
Wybór metody przeciążonej
Opakowywanie i rozpakowywanie stanowią rozwiązanie wielu typowych
problemów (lub przynajmniej czynią życie programisty wygodniej-
szym). Równocześnie jednak same mogą wprowadzać pewne problemy,
zwłaszcza w obszarze wyboru metody. Wybór metody jest procesem,
w którym kompilator języka Java ustala metodę, jaką należy wywołać.
Należy pamiętać, że opakowywanie i rozpakowywanie mają wpływ na
przebieg tego procesu.
98 Rozdział 4: Automatyczne opakowywanie i rozpakowywanie
Jak to osiągnąć?
W zwykłej sytuacji wybór metody w języku Java odbywa się na podsta-
wie nazwy metody. Jednak w przypadku, gdy nazwa metody jest prze-
ciążona, konieczne staje się wykonanie dodatkowego kroku. Wersja
przeciążonej metody wybierana jest na podstawie dopasowania listy ar-
gumentów. Jeśli dopasowanie to się nie uda, kompilator zgłosi błąd.
Brzmi prosto, prawda? Wezmy pod uwagę poniższe dwie metody:
public void doSomething(double num);
public void doSomething(Integer num);
Załóżmy teraz, że metodę doSomething() wywołaliśmy w następujący
sposób:
int foo = 1;
doSomething(foo);
Która metoda zostanie wywołana? We wcześniejszych wersjach języka
Java jej ustalenie nie sprawi nam kłopotu. Wartość typu int zostanie
rozszerzona do typu double i wywołana zostanie metoda doSomething
(double num). Jednak w wersji Tiger wydaje się, że nastąpi opakowa-
nie wartości typu int i wywołana zostanie metoda doSomething(int
num). Chociaż taki sposób działania wydaje się sensowny, jednak tak się
nie stanie.
Wyobrazmy sobie sytuację, w której napisalibyśmy powyższy program,
skompilowali go i przetestowali w języku Java 1.4, a następnie w wersji
Tiger. Okazałoby się, że działa on różnie w zależności od wersji języka.
Dlatego też obowiązuje zasada, że w wersji Tiger zawsze zostanie wy-
brana ta sama metoda, która zostałaby wybrana w wersji 1.4. W prak-
tyce powinniśmy unikać takiego korzystania z przeciążania jak w po-
wyższym przykładzie. Jeśli będziemy dokładnie specyfikować listy
argumentów metod, problem ten przestanie istnieć.
Jak to działa?
Ze względu na wspomnianą zasadę w wersji Tiger wybór metody odby-
wa się w trzech etapach:
Wybór metody przeciążonej 99
1. Kompilator próbuje określić właściwą metodę bez stosowania opera-
Listy argumentów
o zmiennej długości
cji opakowywania i rozpakowywania, a także zmiennych list argu-
omówione zostaną
mentów. Na skutek wykonania tego etapu wybranie zostania taka
w rozdziale 5.
sama metoda jak w przypadku Java 1.4.
2. Jeśli pierwszy etap zawiedzie, kompilator próbuje ponownie znalezć
odpowiednią metodę, ale tym razem stosując opakowywanie i roz-
pakowywanie. Metody mające listy argumentów o zmiennej długości
na tym etapie nie są brane pod uwagę.
3. Jeśli zawiedzie również drugi etap, kompilator podejmuje ostatnią
próbę, uwzględniając opakowywanie i rozpakowywanie, a także listy
argumentów o zmiennej długości.
Zastosowanie powyższych zasad zapewnia spójność działania ze wcze-
śniejszymi wersjami języka Java.
100 Rozdział 4: Automatyczne opakowywanie i rozpakowywanie [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • rafalstec.xlx.pl