Choć Java to język gwarantujący efektywną pracę, to jednak kryje w sobie wiele pułapek, które mogą zniweczyć jej efekty. Książka ta ma za zadanie oszczędzić Twój czas i zapobiec frustracji przeprowadzając Cię bezpiecznie przez skomplikowane zagadnienia. Zespół ekspertów od języka Java pod wodzą guru programowania w osobie Michaela Daconta proponuje Ci zestaw sprawdzonych rozwiązań 50 trudnych problemów pojawiających się w praktyce każdego programisty. Rozwiązania te pozwolą Ci uniknąć problemów wynikających z niedostatków języka Java oraz jego interfejsów programowych, w tym pakietów java.util, java.io, java.awt i javax.swing. Autorzy dzielą się także z Czytelnikiem swoimi sposobami na poprawę wydajności aplikacji pisanych w Javie.
Oto niektóre z omawianych zagadnień:
* Składnia języka: zastosowanie metody equals() zamiast operatora == do porównywania obiektów klasy String
* Funkcjonalność wbudowana w język: rozdział metod a mechanizm refleksji, interfejsy i klasy anonimowe
* Użyteczne klasy i kolekcje: wybór klasy PropertyFile i ResourceBundle
* Wejście i wyjście, w tym subtelności związane z przesyłaniem serializowanych obiektów za pomocą gniazd sieciowych
* Graficzny interfejs użytkownika: sposoby uniknięcia typowej pułapki polegającej na zastosowaniu metody repaint() zamiast metody validate() w celu uzyskania nowego układu komponentów
* Graficzny interfejs użytkownika -- sterowanie: m.in. bardziej funkcjonalna kontrola danych wprowadzanych przez użytkownika
* Wydajność: m.in. zastosowanie odroczonego ładowania, tak by zwiększyć szybkość uruchamiania programów
1. IDZ DO
PRZYK£ADOWY ROZDZIA£
SPIS TRE CI Java. Potrzaski
Autorzy: Michael C. Daconta, Eric Monk,
KATALOG KSI¥¯EK J Paul Keller, Keith Bohnenberger
T³umaczenie: Jaromir Senczyk
KATALOG ONLINE ISBN: 83-7361-121-5
Tytu³ orygina³u: Java Pitfalls
ZAMÓW DRUKOWANY KATALOG Format: B5, stron: 310
Przyk³ady na ftp: 68 kB
TWÓJ KOSZYK
DODAJ DO KOSZYKA Choæ Java to jêzyk gwarantuj¹cy efektywn¹ pracê, to jednak kryje w sobie wiele
pu³apek, które mog¹ zniweczyæ jej efekty. Ksi¹¿ka ta ma za zadanie oszczêdziæ Twój
czas i zapobiec frustracji przeprowadzaj¹c Ciê bezpiecznie przez skomplikowane
CENNIK I INFORMACJE zagadnienia. Zespó³ ekspertów od jêzyka Java pod wodz¹ guru programowania
w osobie Michaela Daconta proponuje Ci zestaw sprawdzonych rozwi¹zañ 50 trudnych
ZAMÓW INFORMACJE problemów pojawiaj¹cych siê w praktyce ka¿dego programisty. Rozwi¹zania te pozwol¹
O NOWO CIACH Ci unikn¹æ problemów wynikaj¹cych z niedostatków jêzyka Java oraz jego interfejsów
programowych, w tym pakietów java.util, java.io, java.awt i javax.swing. Autorzy dziel¹
ZAMÓW CENNIK siê tak¿e z Czytelnikiem swoimi sposobami na poprawê wydajno ci aplikacji pisanych
w Javie.
Oto niektóre z omawianych zagadnieñ:
CZYTELNIA • Sk³adnia jêzyka: zastosowanie metody equals() zamiast operatora ==
do porównywania obiektów klasy String
FRAGMENTY KSI¥¯EK ONLINE • Funkcjonalno æ wbudowana w jêzyk: rozdzia³ metod a mechanizm refleksji,
interfejsy i klasy anonimowe
• U¿yteczne klasy i kolekcje: wybór klasy PropertyFile i ResourceBundle
• Wej cie i wyj cie, w tym subtelno ci zwi¹zane z przesy³aniem serializowanych
obiektów za pomoc¹ gniazd sieciowych
• Graficzny interfejs u¿ytkownika: sposoby unikniêcia typowej pu³apki polegaj¹cej
na zastosowaniu metody repaint() zamiast metody validate() w celu uzyskania
nowego uk³adu komponentów
• Graficzny interfejs u¿ytkownika -- sterowanie: m.in. bardziej funkcjonalna kontrola
danych wprowadzanych przez u¿ytkownika
• Wydajno æ: m.in. zastosowanie odroczonego ³adowania, tak by zwiêkszyæ
Wydawnictwo Helion szybko æ uruchamiania programów
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl
2. Spis treści
Wstęp ............................................................................................... 9
Rozdział 1. Składnia języka................................................................................ 13
Zagadnienie 1. Przesłanianie metod statycznych ........................................................14
Zagadnienie 2. Zastosowanie metody equals() i operatora ==
dla obiektów klasy String ......................................................................................16
Zagadnienie 3. Kontrola zgodności typów w języku Java ...........................................19
Konwersja typów..............................................................................................20
Rozszerzanie ....................................................................................................21
Zawę anie ........................................................................................................22
Niejawne konwersje typów ................................................................................22
Zagadnienie 4. Czy to jest konstruktor? ....................................................................23
Zagadnienie 5. Brak dostępu do przesłoniętej metody ................................................25
Zagadnienie 6. Pułapka ukrytego pola.......................................................................27
Rodzaje zmiennych w języku Java .....................................................................29
Zakres deklaracji zmiennej.................................................................................29
Które zmienne mogą być ukrywane? ..................................................................30
Ukrywanie zmiennych instancji i zmiennych klas.................................................30
Dostęp do ukrytych pól......................................................................................32
Ró nice pomiędzy ukrywaniem pól i przesłanianiem metod..................................33
Zagadnienie 7. Referencje wyprzedzające.................................................................34
Zagadnienie 8. Konstruktory i projektowanie klas......................................................35
Zagadnienie 9. Przekazywanie typów prostych przez referencję..................................42
Zagadnienie 10. Wyra enia i operatory logiczne ........................................................45
Rozdział 2. Funkcjonalność wbudowana w język Java ......................................... 47
Zagadnienie 11. Odzyskiwanie pamięci za pomocą obiektów SoftReference ................48
Odzyskiwanie pamięci.......................................................................................48
Klasa SoftReference..........................................................................................50
Kolejki referencji ..............................................................................................55
Zagadnienie 12. Zakleszczenie na skutek wywołania metody synchronizowanej
przez metodę synchronizowaną .............................................................................57
Wątki, monitory i słowo kluczowe synchronized..................................................57
Przykładowy scenariusz zakleszczenia ................................................................61
Zagadnienie 13. Klonowanie obiektów .....................................................................65
Zagadnienie 14. Przesłanianie metody equals ............................................................71
Zastosowanie obiektów klasy StringBuffer jako kluczy kodowania mieszającego ...73
Zagadnienie 15. Unikajmy konstruktorów w implementacji metody clone() .................74
3. 6 Java. Potrzaski
Zagadnienie 16. Rozdział metod a mechanizm refleksji, interfejsy
i klasy anonimowe................................................................................................79
Zagadnienie 17. Obsługa wyjątków i błąd OutOfMemoryError ...................................88
Składnia wyjątków............................................................................................89
Hierarchia wyjątków .........................................................................................89
Obsługa wyjątków ............................................................................................90
Błąd braku pamięci ...........................................................................................90
Rozdział 3. Użyteczne klasy i kolekcje ............................................................... 93
Zagadnienie 18. Uporządkowane klucze właściwości? ...............................................94
Zagadnienie 19. Obsługa kolekcji o znacznych rozmiarach
za pomocą mechanizmów buforowania i trwałości...................................................97
Zagadnienie 20. Plik właściwości czy zestaw zasobów? ........................................... 109
Zagadnienie 21. Pułapki klasy Properties ................................................................ 112
Zagadnienie 22. Klasa Vector i nowe kolekcje......................................................... 117
Rozdział 4. Wejście i wyjście ........................................................................... 121
Zagadnienie 23. Serializacja................................................................................... 122
Jak działa serializacja?..................................................................................... 123
Interfejs Externalizable .................................................................................... 124
Zagadnienie 24. Unicode, UTF i strumienie............................................................. 125
Unicode ......................................................................................................... 126
UTF .............................................................................................................. 126
Strumienie...................................................................................................... 128
Konfigurowanie kodowania ............................................................................. 131
Zagadnienie 25. Przesyłanie serializowanych obiektów
za pomocą gniazd sieciowych .............................................................................. 131
Zagadnienie 26. Try, catch … finally? .................................................................... 135
Zagadnienie 27. Opró nianie zasobów związanych z obrazami ................................. 138
Rozdział 5. Graficzny interfejs użytkownika — prezentacja................................ 143
Zagadnienie 28. Informowanie o postępach............................................................. 144
Kursor zajętości .............................................................................................. 145
Monitor postępu.............................................................................................. 147
Zagadnienie 29. Zastosowanie metody repaint() zamiast metody validate()
do aktualizacji układu komponentów.................................................................... 149
Zagadnienie 30. Uporządkowanie nakładających się komponentów........................... 153
Mened ery układu........................................................................................... 154
JLayeredPane ................................................................................................. 158
Zagadnienie 31. Zagadka metod validate(), revalidate() i invalidate()......................... 160
Zagadnienie 32. Pionowy układ komponentów ........................................................ 164
Zagadnienie 33. Właściwe sposoby u ycia mened era GridBagLayout ...................... 172
Zagadnienie 34. Zapobieganie migotaniu obrazu ..................................................... 179
Rysowanie w AWT......................................................................................... 180
Rysowanie i Swing.......................................................................................... 183
Zagadnienie 35. Komponenty z zagnie d onymi etykietami HTML .......................... 184
Rozdział 6. Graficzny interfejs użytkownika — sterowanie ................................ 189
Zagadnienie 36. Kontrola danych wprowadzanych przez u ytkownika ...................... 190
Komponenty tworzone na miarę ....................................................................... 191
Filtrowanie ..................................................................................................... 191
Konsumowanie zdarzeń................................................................................... 192
Kontrola po wprowadzeniu danych................................................................... 194
Problemy projektowania .................................................................................. 194
4. Spis treści 7
Asynchroniczna kontrola poprawności .............................................................. 195
Adapter kontroli danych .................................................................................. 196
Techniki kontroli poprawności danych.............................................................. 198
Kontrola poprawności danych z wykorzystaniem wyjątków................................ 198
Łańcuchy kontroli poprawności danych ............................................................ 200
Uwagi końcowe .............................................................................................. 201
Zagadnienie 37. Uaktywnianie komponentów interfejsu u ytkownika
w zale ności od stanu aplikacji ............................................................................ 201
Pierwsze rozwiązanie ...................................................................................... 202
Rozwiązanie siłowe......................................................................................... 202
Rozwiązanie przez abstrakcję — klasa StateMonitor .......................................... 203
ListViewer ..................................................................................................... 205
Adaptacyjna deaktywacja komponentów........................................................... 208
Zagadnienie 38. Wielowątkowa obsługa zdarzeń ..................................................... 208
Skuteczna implementacja obsługi przycisku Cancel
z wykorzystaniem wątków............................................................................. 210
Skuteczna implementacja obsługi przycisku Cancel
wykorzystująca klasę SwingWorker ............................................................... 212
Zagadnienie 39. Wzorzec „model widok kontroler” i komponent JTree ..................... 214
Zagadnienie 40. Przekazywanie danych innych ni tekst .......................................... 217
Pakiet java.awt.datatransfer ............................................................................. 218
Trzy scenariusze przekazywania danych ........................................................... 219
Przykład przekazywania danych w obrębie jednej maszyny wirtualnej ................. 219
Określanie sposobu przekazywania danych ....................................................... 223
Przekazywanie danych poza maszynę wirtualną................................................. 224
Zagadnienie 41. KeyListener, który nie słucha? ....................................................... 238
Zagadnienie 42. Drukowanie tekstu, dokumentów HTML i obrazów
za pomocą komponentu JEditorPane .................................................................... 241
Rozdział 7. Efektywność.................................................................................. 251
Zagadnienie 43. Odroczone ładowanie sposobem na poprawę efektywności............... 252
Zagadnienie 44. Zastosowania puli obiektów........................................................... 254
Odzyskiwanie obiektów................................................................................... 255
Porównanie puli obiektów i buforowania........................................................... 255
Implementacja ................................................................................................ 256
Zalety ............................................................................................................ 257
Wady............................................................................................................. 258
Kłopoty.......................................................................................................... 258
Zagadnienie 45. Efektywność tablic i klasy Vector................................................... 260
Dlaczego klasa Vector jest wolniejsza od zwykłych tablic? ................................. 262
Kiedy u ywać klasy Vector? ............................................................................ 263
Klasa ArrayList............................................................................................... 264
Zagadnienie 46. Zagadnienie dynamicznego wzrostu tablic ...................................... 265
Zagadnienie 47. Konkatenacja łańcuchów znakowych w pętli
— porównanie klas String i StringBuffer .............................................................. 270
Rozdział 8. Rozmaitości................................................................................... 273
Zagadnienie 48. Czy istnieje lepszy sposób uruchamiania? ....................................... 273
Zagadnienie 49. Hermetyzacja wywołań JNI za pomocą interfejsów ......................... 275
Koncepcja ...................................................................................................... 276
Przykład interfejsu .......................................................................................... 277
Implementacja w języku Java........................................................................... 279
Implementacja w kodzie macierzystym ............................................................. 281
Kod specyficzny dla platformy Windows .......................................................... 285
5. 8 Java. Potrzaski
Zagadnienie 50. Asercje ........................................................................................ 289
Asercje w języku Java ..................................................................................... 290
Stosowanie asercji........................................................................................... 290
Jak nie nale y stosować asercji......................................................................... 290
Przykładowa implementacja............................................................................. 291
Skorowidz .......................................................................................... 295
6. Rozdział 3.
Użyteczne klasy i kolekcje
W językach C++ i Java implementacja list jest dostępna w standardowych
bibliotekach, co nie zwalnia nas od znajomości sposobów ich stosowania.
— Brian W. Kernighan i Rob Pike „The Practice Of Programming”
Aby z powodzeniem u ywać jakiekolwiek klasy, nale y dobrze znać sposób, w jaki zo-
stały zaprojektowane ich zadania i ograniczenia. Wymaga to czasu i doświadczenia. Dla-
tego, aby zaoszczędzić Czytelnikowi czas przedstawiamy w niniejszym rozdziale własne
doświadczenia — niektóre klasy pakietu LCXCWVKN ujęte w pięć następujących zagadnień:
Zagadnienie 18. Uporządkowane klucze właściwości? — opisuje sposób udoskona-
lenia klasy 2TQRGTVKGU dający uporządkowany zbiór właściwości.
Zagadnienie 19. Obsługa kolekcji o znacznych rozmiarach za pomocą mechani-
zmów buforowania i trwałości — szczegółowo omawia sposób implementacji ko-
lekcji wykorzystujący mechanizmy buforowania i trwałości stanowiącej rozwiązanie
rzeczywistego problemu zaczerpniętego z praktyki programistycznej.
Zagadnienie 20. Plik właściwości czy zestaw zasobów? — przedstawia ró nice po-
między rozwiązaniami wymienionymi w tytule. Mimo e pliki właściwości stanowią
często stosowane rozwiązanie, to nie zawsze jest ono optymalne. W zagadnieniu przed-
stawiono przykład ilustrujący taką sytuację.
Zagadnienie 21. Pułapki klasy Properties — stanowi dokładny przegląd zagadnień
i pułapek związanych z zastosowaniem właściwości do przechowywania informacji
o konfiguracji programów. W szczególności omawia sposoby umo liwiające pracę apli-
kacji w ró nych systemach niezale nie od sposobu jej instalacji.
Zagadnienie 22. Klasa Vector i nowe kolekcje — szczegółowo opisuje modyfikacje
klasy 8GEVQT na skutek włączenia jej do szkieletu kolekcji udostępnionego w nowszych
wersjach języka Java. Zagadnienie ma zachęcić Czytelnika do korzystania z nowego
szkieletu kolekcji.
7. 94 Java. Potrzaski
Zagadnienie 18.
Uporządkowane klucze właściwości?
Załó my, e Czytelnik wrócił właśnie z udanych wakacji i zamierza pochwalić się ro-
dzinie zdjęciami, które zrobił nowym aparatem. Odkurzając rzutnik i zawieszając ekran,
zaczyna się jednak zastanawiać, czy taka technologia prezentacji zdjęć nie jest ju
przestarzała? Zamiast niej decyduje się napisać program w języku Java, który będzie
zarządzać pokazem zdjęć. Łącząc umiejętności programowania z cyfrowymi zdjęcia-
mi, mo na zrobić na rodzinie jeszcze większe wra enie.
Program jest skończony i nadszedł właśnie długo oczekiwany dzień pokazu. Wujek Bob
i inni zasiedli wokół komputera. Zostaje uruchomiony program, który wyświetla tytuł
pokazu „Wycieczka na Grenadę, wyspę pieprzu”.
Autor zdjęć rozpoczyna opowieść o wakacjach, mówiąc: „Następne zdjęcie obrazuje
moment, gdy z Patty wsiadamy do samolotu”. Jednak po naciśnięciu klawisza, które
to wyświetli, pojawia się zdjęcie twoich przyjaciół, Drew i Suzy, w hotelu. Okazuje
się, e zdjęcia zupełnie się pomieszały. Gdy wujek Bob zaczyna rzucać pomidorami
w ekran monitora, łatwo się domyśleć, e pokaz nie udał się. Jednak zostaje zło one
postanowienie dopracowania programu, aby spróbować jeszcze raz.
Ka dy byłby zdeterminowany, aby znaleźć błąd, który stał się przyczyną pora ki. Klu-
czową koncepcją programu SlideShow jest abstrakcja ście ek dostępu do zdjęć. Dzię-
ki temu stworzenie kolejnego pokazu będzie wymagać jedynie zmiany pliku właściwo-
ści zawierającego ście ki dostępu do wyświetlanych zdjęć. Rozwiązanie takie jest o wiele
lepsze ni konieczność modyfikowania kodu źródłowego za ka dym razem, gdy chce
się stworzyć nową prezentację. Poniewa w pliku właściwości oprócz ście ek dostępu
do poszczególnych zdjęć są zapisane tak e inne informacje, to trzeba przyjąć pewną
konwencję pozwalającą ustalić, która właściwość dotyczy zdjęcia, a która nie. W tym
celu wszystkie właściwości zdjęć poprzedzimy przedrostkiem +OCIGA. Wydaje się to
dobrym rozwiązaniem, jednak zdjęcia nie są wyświetlane we właściwej kolejności.
Sprawdźmy zatem, czy plik właściwości zawiera rzeczywiście opis zdjęć w odpowied-
niej kolejności. Zawartość pliku wygląda następująco:
KOCIG4QQVEKOCIGU
VKVNG)TGPCFC 8CECVKQP
VKVNG2CIG 1WT 6TKR VQ )TGPCFC VJG +UNCPF QH 5RKEG
+OCIGAFGRCTVKPIRNCPGLRI
+OCIGAJQVGNJQVGNLRI
+OCIGAHTKGPFUFTGYAUW[LRI
+OCIGADGCEJDGCEJLRI
+OCIGATGVWTPRCVV[AMKTUVGPAMGKVJLRI
Poniewa kolejność zdjęć w pliku właściwości jest prawidłowa, powodem ich przy-
padkowego wyświetlania musi być błąd w programie. Przyjrzyjmy się więc fragmento-
wi kodu, który jest odpowiedzialny za tworzenie obiektów +OCIG+EQP na podstawie
właściwości zdjęć zapisanych w pliku:
8. Rozdział 3. ♦ Użyteczne klasy i kolekcje 95
RWDNKE +OCIG+EQP=? IGV+OCIGU
]
+OCIG+EQP=? KOCIGU PWNN
#TTC[.KUV CN PGY #TTC[.KUV
5VTKPI KOCIG4QQV RTQRGTVKGUIGV2TQRGTV[
KOCIG4QQV
'PWOGTCVKQP MG[U RTQRGTVKGUMG[U
9JKNG
MG[UJCU/QTG'NGOGPVU
]
5VTKPI MG[
5VTKPIMG[UPGZV'NGOGPV
KH
MG[UVCTVU9KVJ
+OCIGA
]
+OCIG+EQP KEQP PGY +OCIG+EQP
KOCIG4QQV
(KNGUGRCTCVQT
RTQRGTVKGUIGV2TQRGTV[
MG[
CNCFF
KEQP
_
_
KPV UKG CNUKG
KH
UKG
]
KOCIGU PGY +OCIG+EQP=UKG?
CNVQ#TTC[
KOCIGU
_
TGVWTP KOCIGU
_
Metoda IGV+OCIGU
zwraca tablicę obiektów +OCIG+EQP. Tablica ta jest wypełniana
w miarę przeglądania kluczy właściwości i sprawdzania, czy rozpoczynają się one od
przedrostka +OCIGA (wiersz 10.). Jeśli klucz zawiera taki przedrostek, to tworzony jest
obiekt klasy +OCIG+EQP i wstawiany do tablicy klasy #TTC[.KUV (wiersze 12. – 14.). Po
zakończeniu analizy pliku właściwości tablica #TTC[.KUV jest konwertowana do zwykłej
tablicy obiektów klasy +OCIG+EQP i zwraca jako wynik wykonania metody.
Wydaje się więc, e kod programu jest napisany prawidłowo. Jednak skoro tak e plik
właściwości jest prawidłowy, to program powinien wyświetlać zdjęcia w odpowiedniej
kolejności, a tak nie jest. Nale y więc raz jeszcze sprawdzić kod programu, dodając poni -
szą instrukcję wewnątrz bloku instrukcji warunkowej, rozpoczynającej się w wierszu10.:
5[UVGOQWVRTKPVNP
MG[
MG[
Dzięki niej dowiemy się, czy pobieramy ście ki dostępu do zdjęć w tej samej kolejno-
ści, w której zostały one zapisane w pliku właściwości. Uruchamiając program, uzy-
ska się następującą informację:
MG[ +OCIGAJQVGN
MG[ +OCIGAHTKGPFU
MG[ +OCIGAFGRCTVKPI
MG[ +OCIGATGVWTP
MG[ +OCIGADGCEJ
Widzimy więc, e kolejność uzyskiwania zdjęć ró ni się od kolejności ich występowa-
nia w pliku. Czy to oznacza, e metoda MG[U
klasy 2TQRGTVKGU posiada błędy? Od-
powiedź na to pytanie jest krótka: nie. Źródłem problemu jest przyjęte zało enie, e
klucze obiektu 2TQRGTVKGU są widziane w tej samej kolejności, w której występują w pli-
ku. Zało enie to nie jest prawdziwe. Poniewa klasa 2TQRGTVKGU stanowi klasę pochodną
9. 96 Java. Potrzaski
klasy *CUJVCDNG, to klucze właściwości przechowywane są w tablicy mieszającej, a nie
na uporządkowanej liście. Klasa *CUJVCDNG przyznaje ka demu kluczowi indeks zale ny
od wyniku funkcji mieszającej dla danego klucza i od bie ącego rozmiaru tablicy. In-
deks ten nie zale y od kolejności, w której klucze są umieszczane w tablicy. Natomiast
metoda MG[U
zwraca klucze zgodnie z numerycznym porządkiem ich indeksów. Dla-
tego te porządek ich oglądania mo e ró nić się od kolejności, w której zostały umiesz-
czone w tablicy mieszącej.
Czy oznacza to, e musimy umieścić informacje o zdjęciach w kodzie programu, aby
uzyskać po ądaną kolejność ich wyświetlania? Na szczęście nie. Istnieją inne sposo-
by, dzięki którym mo na osiągnąć po ądany efekt, np. umieścić ście ki dostępu do
zdjęć w zwykłym pliku tekstowym nieposiadającym adnej struktury i wczytywać je-
go zawartość. Poniewa jednak program SlideShow korzysta tak e z innych właści-
wości, to musielibyśmy dostarczać mu dwóch ró nych plików. Poza tym mo liwość
przeglądania kluczy obiektu 2TQRGTVKGU w kolejności, w której występują one w pliku
właściwości, mo e okazać się przydatna w wielu innych zastosowaniach.
W jaki sposób zatem uzyskać uporządkowaną listę kluczy z obiektu 2TQRGTVKGU? Nie
jest to mo liwe. Mo emy jednak stworzyć własną klasę pochodną klasy 2TQRGTVKGU,
która zrealizuje to zadanie. Klasa ta będzie posiadać zmienną instancji, która prze-
chowa uporządkowane klucze. Aby móc dodawać klucze i usuwać je z uporządkowanej
listy, musimy tak e przesłonić metody RWV
i TGOQXG
własną implementacją oraz do-
dać metodę, za pomocą której będzie mo na uzyskać uporządkowaną listę kluczy.
Nową klasę nazwiemy 'PJCPEGF2TQRGTVKGU (w zagadnieniu 21. przedstawiono szereg
przydatnych metod tej klasy). Definicja klasy 'PJCPEGF2TQRGTVKGU mo e wyglądać na-
stępująco:
RWDNKE ENCUU 'PJCPEGF2TQRGTVKGU GZVGPFU 2TQRGTVKGU
]
MQPUVTWMVQT[
#TTC[.KUV QTFGTGF-G[U PGY #TTC[.KUV
RWDNKE U[PEJTQPKGF 1DLGEV RWV
1DLGEV MG[ 1DLGEV XCNWG
]
1DLGEV QDLGEV UWRGTRWV
MG[ XCNWG
QTFGTGF-G[UCFF
MG[
TGVWTP QDLGEV
_
RWDNKE U[PEJTQPKGF 1DLGEV TGOQXG
1DLGEV MG[
]
1DLGEV QDLGEV UWRGTTGOQXG
MG[
QTFGTGF-G[UTGOQXG
MG[
TGVWTP QDLGEV
_
RWDNKE U[PEJTQPKGF +VGTCVQT IGV1TFGTGF-G[U
]
TGVWTP QTFGTGF-G[UKVGTCVQT
_
_
10. Rozdział 3. ♦ Użyteczne klasy i kolekcje 97
Zmienna instancji QTFGTGF-G[U w wierszu 5. jest kontenerem, w którym przechowuje się
uporządkowaną listę kluczy. Metoda RWV
, której definicja rozpoczyna się w wierszu 8.,
wywołuje najpierw metodę UWRGTRWV
, która umieszcza klucz w tablicy mieszającej
w sposób właściwy klasie 2TQRGTVKGU. Natomiast wywołanie QTFGTGF-G[UCFF
MG[
w wierszu 9. wstawia ten klucz na uporządkowaną listę kluczy. Wywołanie metody RWV
spowoduje za ka dym razem dodanie klucza do tablicy mieszającej *CUJVCDNG i wsta-
wienie go do uporządkowanej listy kluczy. Metoda TGOQXG
, której definicja rozpoczy-
na się w wierszu 13., działa w podobny sposób do metody RWV
. Za ka dym razem,
gdy wywołana jest metoda TGOQXG
, klucz zostaje najpierw usunięty z tablicy mieszą-
cej, a następnie z uporządkowanej listy kluczy. Dostęp do tej listy umo liwia metoda
IGV1TFGTGF-G[U
, która zwraca iterator czytający tę listę.
Ta dość prosta w implementacji klasa pozwoli przeglądać ście ki dostępu do zdjęć do-
kładnie w tym samym porządku, w którym zostały one zapisane w pliku właściwości.
Metoda IGV+OCIGU
tworząca tablicę obiektów klasy +OCIG+EQP na podstawie właści-
wości, których klucz rozpoczyna się od przedrostka +OCIGA, musi zostać zmodyfikowana
w niewielkim stopniu. Wiersze 6. – 9. trzeba zatem zastąpić następującymi wierszami:
+VGTCVQT QTFGTGF-G[U RTQRGTVKGUIGV1TFGTGF-G[U
9JKNG
MG[UJCU0GZV
]
5VTKPI MG[
5VTKPIMG[UPGZV
Jedyną zmianą, której będziemy musieli wykonać w pozostałej części programu, bę-
dzie zastąpienie instancji klasy 2TQRGTVKGU tworzonej podczas wczytywania zawartości
pliku właściwości za pomocą instancji nowej klasy 'PJCPEGF2TQRGTVKGU. Po wykona-
niu tych zmian i uruchomieniu programu uzyskamy następującą informację o dodawa-
nych kluczach:
MG[ +OCIGAFGRCTVKPI
MG[ +OCIGAJQVGN
MG[ +OCIGAHTKGPFU
MG[ +OCIGADGCEJ
MG[ +OCIGATGVWTP
Ście ki dostępu do plików są teraz uporządkowane w odpowiedni sposób. Wiadomo ju ,
e klasa 2TQRGTVKGU jest pochodną klasy *CUJVCDNG, a sposób przyznawania indeksów
kluczom umieszczanym w tablicy mieszającej nie jest związany z kolejnością ich wsta-
wiania. Dzięki temu mo na spokojnie zaprosić wujka Boba na powtórny, udany po-
kaz zdjęć.
Zagadnienie 19. Obsługa kolekcji
o znacznych rozmiarach za pomocą
mechanizmów buforowania i trwałości
Czasami zdarza się, e program napisany w języku Java, który wyświetla wyniki za-
pytań wysyłanych do systemu baz danych, działa doskonale w 9 przypadkach na 10.
11. 98 Java. Potrzaski
W tym jednym nie wyświetla adnych efektów zapytania, sygnalizując jednocześnie
wystąpienie błędu 1WV1H/GOQT[. Wyniki zapytań są umieszczane w klasie LCXCWVKN
8GEVQT, która stanowi efektywną i wygodną metodę krótkotrwałego przechowywania
danych. W jaki sposób mo na pogodzić efektywność tego rozwiązania z konieczno-
ścią zapewnienia jego niezawodności w przypadku sporadycznie pojawiających się
wyników zapytań o znacznych rozmiarach? Rozwiązaniem będzie struktura danych
stanowiąca kombinację bufora LRU (Least Recently Used) z trwałym składem obiek-
tów. Jego implementację stanowić będzie klasa 2GTUKUVGPV%CEJG8GEVQT, którą omówi-
my w tym zagadnieniu.
Rysunek 3.1 przedstawia strukturę klasy 2GTUKUVGPV%CEJG8GEVQT z zaznaczeniem, e
składa się ona z czterech głównych komponentów: wektora proxy zawierającego namiast-
ki, tablicy mieszającej buforowanych obiektów, listy LRU i obiektu klasy 1DLGEV(KNG
umo liwiającego serializację obiektów.
Rysunek 3.1.
Architektura klasy
PersistentCacheVector
Architektura przedstawiona na rysunku 3.1 posiada następujące zalety:
Prostota u ycia podobna do klasy LCXCWVKN8GEVQT.
Mo liwość osiągania znacznych rozmiarów przez kolekcję (na przykład ponad
50 000 elementów) bez obawy wystąpienia błędu 1WV1H/GOQT['TTQT.
Dostępność najczęściej wykorzystywanych elementów kolekcji w pamięci.
Szczegóły implementacji związane z obsługą kolekcji znacznych rozmiarów
nie są widoczne dla u ytkownika klasy.
12. Rozdział 3. ♦ Użyteczne klasy i kolekcje 99
Architekturę tę będzie implementować kod umieszczony w dwóch plikach źródłowych:
PersistentCacheVector.java i ObjectFile.java. Najpierw zostaną omówione najistotniej-
sze ich fragmenty, a pełny kod źródłowy — pod koniec bie ącego zagadnienia. Zanim
przejdziemy do analizy kodu, przyjrzyjmy się zaproponowanemu interfejsowi klasy
2GTUKUVGPV%CEJG8GEVQT. Posiada on następujące metody o dostępie publicznym:
RWDNKE 2GTUKUVGPV%CEJG8GEVQT
KPV K%CEJG5KG
RWDNKE HKPCN XQKF CFF
5GTKCNKCDNG Q VJTQYU +1'ZEGRVKQP
RWDNKE HKPCN 1DLGEV IGV
KPV KFZ VJTQYU +PFGZ1WVQH$QWPFU'ZEGRVKQP
+1'ZEGRVKQP
RWDNKE HKPCN 1DLGEV TGOQXG
KPV KPFGZ VJTQYU +PFGZ1WV1H$QWPFU'ZEGRVKQP
+1'ZEGRVKQP
RWDNKE HKPCN XQKF EQR[6Q
1DLGEV Q#TTC[ =? VJTQYU +1'ZEGRVKQP
RWDNKE HKPCN XQKF ENQUG
RWDNKE HKPCN XQKF HKPCNKG
RWDNKE HKPCN KPV UKG
Pomiędzy interfejsem klasy 2GTUKUVGPV%CEJG8GEVQT i metodami klasy 8GEVQT wystę-
pują cztery istotne ró nice:
Konstruktor klasy 2GTUKUVGPV%CEJG8GEVQT wymaga określenia maksymalnego
rozmiaru bufora. Inaczej ni w przypadku klasy 8GEVQT, konstruktorowi
której przekazujemy początkowy rozmiar wektora, dla klasy 2GTUKUVGPV%CEJG
8GEVQT parametr konstruktora oznacza maksymalną liczbę obiektów, które
mogą być przechowywane w pamięci. Obiekty nadmiarowe będą przechowane
na dysku.
Niektóre z metod wyrzucają wyjątek +1'ZEGRVKQP ze względu
na przechowywanie obiektów w plikach. Z punktu widzenia zgodności
z klasą 8GEVQT najlepiej obsługiwać ten wyjątek wewnątrz metod, zamiast
przekazywać go do kodu wywołującego metody. Jednak wystąpienie błędu
dysku spowodowałoby wtedy nieprzewidziane zachowanie klasy 8GEVQT. Druga
mo liwość polega na przechwyceniu wyjątku +1'ZEGRVKQP i wyrzuceniu wyjątku
4WPVKOG'ZEGRVKQP, który nie musi być obsługiwany. W ten sposób równie
uzyskalibyśmy przezroczystość fasady klasy 8GEVQT, gdy kod wywołujący
metody nie musiałby obsługiwać adnych wyjątków.
Pominięte zostały niektóre metody dostępne w klasie 8GEVQT. Ich implementację
pozostawiono Czytelnikowi jako ćwiczenie do wykonania. Inna mo liwość
udawania klasy 8GEVQT polega na utworzeniu jej klasy pochodnej i przesłonięciu
wszystkich metod klasy bazowej. Dzięki temu będziemy mogli u ywać obiektów
klasy 2GTUKUVGPV%CEJG8GEVQT zamiast obiektów klasy 8GEVQT, jednak w istotny
sposób zwiększy to rozmiary implementacji klasy 2GTUKUVGPV%CEJG8GEVQT.
Parametrem metody CFF
mogą być tylko obiekty implementujące
interfejs 5GTKCNKCDNG. Ograniczenie to wynika z konieczności zapewnienia
trwałości buforowanych obiektów i oczywiście nie występuje ono w klasie
8GEVQT. Dla zapewnienia zgodności z klasą 8GEVQT metoda CFF
mogłaby
przyjmować dowolne obiekty, a następnie za pomocą refleksji sprawdzać
mo liwość ich serializacji. Jednak wydaje się, e lepiej zapewnić kontrolę
zgodności typów parametrów kosztem pełnej zgodności z klasą 8GEVQT.
13. 100 Java. Potrzaski
Implementacja interfejsu klasy 2GTUKUVGPV%CEJG8GEVQT wymaga zarządzania struktura-
mi przedstawionymi na rysunku 3.1: wektorem proxy zawierającym obiekty namiastek
5VWD'PVT[, tablicą mieszającą obiektów %CEJG'PVT[, listą LRU i obiektem 1DLGEV(KNG.
Zagadnienia te omówimy szczegółowo.
Klasa wewnętrzna 5VWD'PVT[ stwarza iluzję korzystania z obiektów klasy 8GEVQT. U yt-
kownik spodziewa się zwykłego obiektu klasy 8GEVQT, w którym będzie umieszczać swoje
obiekty. Jednak w rzeczywistości będą umieszczane tam instancje klasy 5VWD'PVT[ wska-
zujące, gdzie znajdują się właściwe obiekty. Natomiast właściwe obiekty zostaną umiesz-
czone w buforze lub na dysku (w obiekcie 1DLGEV(KNG). Klasa 5VWD'PVT[ posiada tylko
dwie składowe: znacznik informujący o tym, czy obiekt znajduje się w buforze oraz in-
deks dostępu do obiektu znajdującego się na dysku:
ENCUU 5VWD'PVT[
]
19. NQPI HKNG2QKPVGT
_
Klasa wewnętrzna %CEJG'PVT[ wykorzystywana jest do przechowywania obiektów u yt-
kownika w buforze. Umieszcza tak e klucz w tablicy mieszającej, w której będzie prze-
chowywany obiekt oraz referencje poprzedniego i następnego elementu listy LRU. Ka dy
obiekt klasy %CEJG'PVT[ jest umieszczany w tablicy mieszającej *CUJVCDNG przy zastoso-
waniu klucza, który przechowywany jest tak e wewnątrz danego obiektu klasy %CEJG
'PVT[. Efektywność takiego rozwiązania zmniejsza nieco fakt, e klucz tablicy mie-
szającej musi być obiektem, gdy w rzeczywistości jest on zwykłym indeksem obiektu
5VWD'PVT[ w tablicy. U ycie indeksów tablicy jako kluczy zapewnia przy tym dosko-
nały, bezkolizyjny wynik funkcji mieszającej. Inna, nieco bardziej efektywna mo li-
wość polegałaby na przechowywaniu kluczy w postaci obiektów klasy +PVGIGT w obiek-
tach klasy 5VWD'PVT[. W ten sposób zostałaby ograniczona liczba generowanych kluczy.
Umieszczenie w obiektach klasy %CEJG'PVT[ referencji poprzedniego i następnego ele-
mentu listy sprawia, e pełnią one podwójna funkcję elementu tablicy mieszającej i ele-
mentu dwukierunkowej listy LRU.
ENCUU %CEJG'PVT[
]
28. %CEJG'PVT[ RTGX PGZV
_
Dostęp do dwukierunkowej listy LRU jest mo liwy dzięki referencjom znajdującym
się w klasie 2GTUKUVGPV%CEJG8GEVQT. Jedna z nich wskazuje początek listy (HKTUV%CEJG
'PVT[), a druga jej koniec (NCUV%CEJG'PVT[). Zadaniem listy dwukierunkowej jest okre-
ślenie najrzadziej wykorzystywanego elementu bufora. Za ka dym razem, gdy korzysta-
my z pewnego elementu bufora, zostaje on przesunięty na początek listy. W ten sposób
29. Rozdział 3. ♦ Użyteczne klasy i kolekcje 101
ostatni element listy reprezentuje najrzadziej u ywany element. Większość kodu klasy
2GTUKUVGPV%CEJG8GEVQT właśnie zarządza listą dwukierunkową. Poni ej zaprezentowano
fragment umieszczający instancję klasy %CEJG'PVT[ (o nazwie EG) na liście LRU. Działa
on w następujący sposób: jeśli lista nie jest pusta, to umieszcza nowy element na jej po-
czątku i w nim referencje obiektu, który dotychczas stanowił czoło listy jako referencję
następnego obiektu listy. Po czym referencję obiektu EG umieszcza w obiekcie, który
dotychczas stanowił czoło listy jako referencję poprzedniego elementu listy. Na koniec
nadaje nową wartość referencji wskazującej początek listy. Natomiast w przypadku,
gdy lista jest pusta, inicjuje referencje początku i końca listy za pomocą referencji no-
wego elementu.
YUVCYKC GNGOGPV FQ NKUV[
KH
NCUV%CEJG'PVT[ PWNN
]
WOKGUEC IQ PC RQEæVMW NKUV[
EGPGZV HKTUV%CEJG'PVT[
HKTUV%CEJG'PVT[RTGX EG
HKTUV%CEJG'PVT[ EG
_
GNUG
]
NKUVC LGUV RWUVC
HKTUV%CEJG'PVT[ NCUV%CEJG'PVT[ EG
_
Klasa 1DLGEV(KNG przechowuje serializowane obiekty w pliku o dostępie swobodnym,
reprezentowanym przez klasę 4CPFQO#EEGUU(KNG. Serializowany obiekt jest przechowy-
wany w postaci tablicy bajtów. Aby zapisać tablicę bajtów za pomocą obiektu klasy
4CPFQO#EEGUU(KNG nie są potrzebne adne dodatkowe dane. Jednak, aby odczytać ta-
blicę bajtów z pliku, musimy znać jej wielkość. Dlatego te w pliku jest zapisywana naj-
pierw wartość całkowita, a następnie tablica bajtów. Wartość ta określa liczbę bajtów
tablicy. Klasa 1DLGEV(KNG zawiera instancję klasy 4CPFQO#EEGUU(KNG i implementuje
metody zapisu i odczytu obiektów w omówionej postaci.
RWDNKE ENCUU 1DLGEV(KNG
]
4CPFQO#EEGUU(KNG FCVC(KNG
5VTKPI U(KNG0COG
RWDNKE 1DLGEV(KNG
5VTKPI U0COG VJTQYU +1'ZEGRVKQP
]
U(KNG0COG U0COG
FCVC(KNG PGY 4CPFQO#EEGUU(KNG
U0COG TY
_
Dla potrzeb naszego przykładu klasa 2GTUKUVGPV%CEJG#TTC[ posiada dodatkowo metodę
OCKP
umo liwiającą jej przetestowanie. Poni ej przedstawiamy efekt wykonania te-
stów umieszczonych w tej metodzie:
CFFKPI QDLGEVU
5KG
6GUVKPI IGV
0QY VJG GNGOGPV CV KPFGZ KU
30. 102 Java. Potrzaski
5KG KU
6GUVKPI TGOQXG
5KG
4GOQXKPI
5KG
(KTUV
Oto pełny kod źródłowy klasy 2GTUKUVGPV%CEJG8GEVQT:
117. Rozdział 3. ♦ Użyteczne klasy i kolekcje 109
]
FCVC(KNGENQUG
_
/GVQF[ RQOKPKúVG G YINúFW PC DTCM OKGLUEC
_ MQPKGE MNCU[ 1DLGEV(KNG
W zagadnieniu tym przedstawiono połączenie bufora .47 i klasy umo liwiającej trwałe
przechowywanie obiektów (1DLGEV(KNG), w wyniku którego uzyskano efektywne rozwią-
zanie problemu obsługi sporadycznie pojawiających się kolekcji o znacznych rozmia-
rach. Potrafi ono wydajnie obsłu yć typowy przypadek, w którym występuje niewiele
danych oraz charakteryzuje się niezawodnością w momencie pojawienia się wyjątkowo
du ej ilości danych. Tworzenie takich niezawodnych, choć nie zawsze efektownych roz-
wiązań cechuje najlepszych programistów.
Zagadnienie 20. Plik właściwości
czy zestaw zasobów?
Proszę sobie wyobrazić, e ktoś rozpoczął właśnie pracę dla nowo powstałej firmy
LOA, która zamierza odebrać część internetowego tortu America Online. Dowiedział
się, e Sun Microsystems zgodziła się reklamować usługi firmy, w której ten ktoś za-
cznie pracować, u ytkownikom swojego nowego systemu operacyjnego napisanego
w całości w Javie. System będzie sprzedawany na całym świecie, a dołączana do nie-
go aplikacja firmy LOA na razie pracuje jedynie w języku angielskim. Zadaniem no-
wego pracownika jest wyposa enie jej w mo liwości obsługi innych języków. Ma czas
do końca tygodnia.
Poniewa jako programista jest on odpowiedzialny jedynie za okno pokazywane u yt-
kownikowi podczas uruchamiania programu, to powierzone zadanie wydaje się wyko-
nalne. W obecnej wersji okno to pobiera wyświetlane informacje z pliku właściwości.
Wystarczy więc utworzyć takie pliki zawierające informacje w innych językach i opra-
cować wymienne moduły wyświetlającego je kodu. Jednak mened er informuje, e
jeden i ten sam moduł kodu powinien obsługiwać wszystkie języki. Dlatego kolejnym
pomysłem jest wczytywanie właściwości systemu zawierających informacje o wybranym
języku. Dzięki tej informacji mo liwe będzie następnie wczytanie zawartości odpowied-
niego pliku właściwości. W czasie przerwy w pracy nowy pracownik zwierza się ze
swojego pomysłu jednemu z bardziej doświadczonych programistów. Pochwala on ta-
kie rozwiązanie, informując jednocześnie, e firma Sun dawno je opracowała. Poleca
więc zapoznanie się z klasą 4GUQWTEG$WPFNG.
Klasa 4GUQWTEG$WPFNG ró ni się od klasy 2TQRGTVKGU w wielu aspektach. Klasa 4GUQWTEG
$WPFNG i jej klasy pochodne .KUV4GUQWTEG$WPFNG i 2TQRGTV[4GUQWTEG$WPFNG zaprojek-
towano tak, by wykorzystywały klasę .QECNG do obsługi danych zale nych od kraju,
w którym mieszka u ytkownik programu. Natomiast klasa 2TQRGTVKGU nie u ywa klasy
.QECNG, poniewa jej zadaniem jest jedynie przechowywanie par obiektów klasy 5VTKPI
reprezentujących klucz i odpowiadającą mu wartość. Dlatego te klasę 2TQRGTVKGU,
w przeciwieństwie do klasy 4GUQWTEG$WPFNG, stosujemy do przechowywania łańcuchów
118. 110 Java. Potrzaski
znaków 5VTKPI, które nie podlegają lokalizacji. W ten sposób powinno się oddzielić
w programie dane, które podlegają lokalizacji od tych, które są niezale ne od języka
aplikacji. Kolejna ró nica pomiędzy klasami 4GUQWTEG$WPFNG i klasą 2TQRGTVKGU polega
na tym, e klasa .KUV4GUQWTEG$WPFNG umo liwia przechowywanie klucza klasy 5VTKPI
i wartości klasy 1DLGEV. W praktyce oznacza to, e mo na przechowywać w niej war-
tość będącą obiektem dowolnej klasy. Natomiast klasa 2TQRGTVKGU umo liwia przecho-
wywanie jedynie łańcuchów znakowych klasy 5VTKPI.
Pierwszym krokiem związanym z internacjonalizacją okna programu będzie określe-
nie, które dane zale ą od lokalizacji u ytkownika. Aby lepiej zrozumieć jakich danych
mo e to dotyczyć, przyjrzyjmy się bli ej klasie .QECNG. Klasa ta musi uwzględniać nie
tylko język, którym posługuje się u ytkownik programu, ale tak e kraj, w którym on
mieszka. W wielu krajach u ywa się bowiem tego samego języka, ale zapisuje liczby
i daty w ró nych formatach. Trzecim parametrem klasy .QECNG jest wariant. Umo liwia
on programiście wyspecjalizowanie dodatkowych ró nic w stosunku do podstawowych
formatów. W naszym przypadku internacjonalizacji będzie podlegać jedynie tekst wy-
świetlany w oknie i na przyciskach.
W celu wyświetlania tekstu w ró nych językach trzeba stworzyć zestaw zasobów klasy
4GUQWTEG$WPFNG zawierający pliki właściwości. Przez zestaw zasobów rozumiemy w tym
przypadku grupę plików zawierających te same dane poddane procesowi lokalizacji
dla ró nych krajów i języków. Takich zestawów zasobów mo emy opracować dowolnie
wiele. W naszym przykładzie stworzymy dwa: jeden zawierający tekst powitania wy-
świetlany w oknie oraz drugi, w którym umieścimy opisy wszystkich przycisków okna.
Poniewa internacjonalizacji podlega jedynie tekst, to zestawy zasobów zawierać będą
tylko pliki właściwości (w ogólnym przypadku mogą to być pliki właściwości i klasy
języka Java). Zaletą takiego rozwiązania jest to, e, oddzielając w ten sposób kod od
danych, mo emy przekazać tłumaczom tylko same pliki właściwości.
Zestaw zasobów uzyskujemy, wywołując metodę 4GUQWTEG$WPFNGIGV$WPFNG
. Prze-
kazuje się jej jako parametr obiekt klasy .QECNG lub pozwala skorzystać z domyślnego
obiektu .QECNG. Aby klasa 4GUQWTEG$WPFNG mogła znaleźć odpowiedni plik właściwo-
ści lub klasę, trzeba zachować odpowiednią konwencję tworzenia nazw plików właści-
wości i klas. Dokumentacja javadoc wyjaśnia dokładnie sposoby tworzenia takich nazw.
Poni ej przedstawiono konwencję nazw w kolejności, w której poszukuje jej kod klasy
4GUQWTEG$WPFNG, aby odnaleźć odpowiedni zasób:
DCUGENCUU
A
NCPIWCIG
A
EQWPVT[
A
XCTKCPV
DCUGENCUU
A
NCPIWCIG
A
EQWPVT[
A
XCTKCPV
RTQRGTVKGU
DCUGENCUU
A
NCPIWCIG
A
EQWPVT[
DCUGENCUU
A
NCPIWCIG
A
EQWPVT[
RTQRGTVKGU
DCUGENCUU
A
NCPIWCIG
DCUGENCUU
A
NCPIWCIG
RTQRGTVKGU
DCUGENCUU
A
NCPIWCIG
A
EQWPVT[
A
XCTKCPV
DCUGENCUU
A
NCPIWCIG
A
EQWPVT[
A
XCTKCPV
RTQRGTVKGU
DCUGENCUU
A
NCPIWCIG
A
EQWPVT[
DCUGENCUU
A
NCPIWCIG
A
EQWPVT[
RTQRGTVKGU
DCUGENCUU
A
NCPIWCIG
DCUGENCUU
A
NCPIWCIG
RTQRGTVKGU
DCUGENCUU
DCUGENCUU
RTQRGTVKGU
119. Rozdział 3. ♦ Użyteczne klasy i kolekcje 111
Załó my na przykład, e metodzie IGV$WPFNG
przekazaliśmy obiekt klasy .QECNG za-
wierający kod języka niemieckiego (FG) i kod Szwajcarii (%*). Domyślny obiekt klasy
.QECNG zawiera natomiast kod języka angielskiego (GP) i Stanów Zjednoczonych (75).
Przypuśćmy, e klasę bazową tekstu powitania nazwaliśmy 5VCTVWR/GUUCIG. Aby ustalić,
jakich nazw zasobów będzie poszukiwać klasa 4GUQWTEG$WPFNG, musimy zastąpić w po-
wy szym schemacie parametr DCUGENCUU nazwą 5VCTVWR/GUUCIG , parametr NCPIWCIG
— łańcuchem FG , parametr EQWPVT[ — łańcuchem %* , parametr NCPIWCIG — łań-
cuchem GP i parametr EQWPVT[ — łańcuchem 75 . Ustalimy w ten sposób, e program
będzie próbować znaleźć kolejno następujące zasoby: 5VCTVWR/GUUCIGAFGA%*, 5VCTVWR
/GUUCIGAFGA%*RTQRGTVKGU, 5VCTVWR/GUUCIGAFG , 5VCTVWR/GUUCIGAFGRTQRGTVKGU ,
5VCTVWR/GUUCIGAGPA75, 5VCTVWR/GUUCIGAGPA75RTQRGTVKGU , 5VCTVWR/GUUCIGAGP,
5VCTVWR/GUUCIGAGPRTQRGTVKGU, 5VCTVWR/GUUCIG, 5VCTVWR/GUUCIGRTQRGTVKGU.
Tworzenie zestawu zasobów najlepiej rozpoczynać zawsze od podstawowego. Dzięki
temu kod zawsze znajdzie przynajmniej podstawowy zasób w przypadku, gdy nie bę-
dzie dostępny zasób odpowiadający przekazanemu lub domyślnemu obiektowi klasy
.QECNG. Najpierw utworzymy więc podstawowy plik właściwości. Będzie on posiadać
nazwę 5VCTVWR/GUUCIG i następującą zawartość:
5VCTVWR5ETGGPOGUUCIG 9GNEQOG VQ .1# 2NGCUG RTGUU 1- VQ KPUVCNN QWT UQHVYCTG
1VJGTYKUG RTGUU %#0%'. VQ GZKV
Następnie utworzymy plik właściwości dla domyślnego obiektu klasy .QECNG o nazwie
5VCTVWR/GUUCIGAGPA75RTQRGTVKGU. Zawiera on takie same informacje jak podstawowy
plik właściwości. Skoro jednak informacja w obu plikach jest identyczna, to po co two-
rzyć plik podstawowy. Załó my, e obiekt klasy .QECNG przekazany metodzie IGV$WPFNG
dotyczy Chin, a obiekt domyślny Japonii. Poniewa zestaw zasobów nie zawiera plików
właściwości dla języka chińskiego ani japońskiego, to posłu y się właśnie plikiem pod-
stawowym. Gdy w zestawie zasobów nie umieścimy pliku podstawowego, wówczas
w opisanym przypadku zostanie wyrzucony wyjątek /KUUKPI4GUQWTEG'ZEGRVKQP.
Następnie utworzymy domyślny zasób opisujący teksty przycisków. Nazwiemy go
5VCTVWR$WVVQPRTQRGTVKGU. Zawiera on następujące informacje:
5VCTVWR$WVVQPQM1-
5VCTVWR$WVVQPECPEGN%#0%'.
Ponownie utworzymy te zasób dla domyślnego obiektu klasy 'PVKV[ o takiej samej za-
wartości. Nazwiemy go 5VCTVWR$WVVQPAGPA75RTQRGTVKGU.
Po oddzieleniu zasobów od kodu programu zobaczmy, w jaki sposób mo e korzystać
z nich program.
Poni szy fragment kodu wczytuje zasób 5VCTVWR/GUUCIG dla domyślnego obiektu kla-
sy .QECNG:
4GUQWTEG$WPFNG UVCTVWR/GUUCIG$WPFNG
UVCTVWR/GUUCIG$WPFNG 4GUQWTEG$WPFNGIGV$WPFNG
5VCTVWR/GUUCIG
5VTKPI OGUUCIG UVCTVWR/GUUCIG$WPFNGIGV5VTKPI
5VCTVWR5ETGGPOGUUCIG
Podobnie poni szy fragment kodu wczyta zasób 5VCTVWR$WVVQP dla domyślnego obiektu
klasy .QECNG:
120. 112 Java. Potrzaski
4GUQWTEG$WPFNG UVCTVWR$WVVQP$WPFNG
UVCTVWR$WVVQP$WPFNG 4GUQWTEG$WPFNGIGV$WPFNG
5VCTVWR$WVVQP
5VTKPI QM$WVVQP UVCTVWR$WVVQP$WPFNGIGV5VTKPI
5VCTVWR$WVVQPQM
Jeśli domyślny obiekt klasy .QECNG odpowiada językowi angielskiemu (GP) i USA (75),
to zostaną załadowane pliki 5VCTVWR/GUUCIGAGPA75RTQRGTVKGU oraz 5VCTVWR$WVVQPA
GPA75RTQRGTVKGU. Zaletą przedstawionego rozwiązania jest to, e kod programu nie
musi zmieniać się ze zmianą języka wyświetlanych komunikatów. Wystarczy, e tłu-
macz stworzy nowy plik właściwości i odpowiednio go nazwie. W ten sposób jeden
i ten sam fragment kodu mo e obsługiwać wiele języków.
Problematyka internacjonalizacji oprogramowania jest rozległa. W zagadnieniu tym skon-
centrowaliśmy się na omówieniu ró nic pomiędzy klasami 2TQRGTVKGU i 4GUQWTEG$WPFNG
i przedstawieniu podstawowych sposobów posługiwania się klasą 4GUQWTEG$WPFNG. Mo -
na więc potraktować go jedynie jako wprowadzenie do tematu. Język Java dysponuje
jeszcze innymi klasami wspierającymi programistę podczas internacjonalizacji pro-
gramów, na przykład CVG(QTOCV, 0WODGT(QTOCV i /GUUCIG(QTOCV.
Zagadnienie 21.
Pułapki klasy Properties
Jeśli Czytelnik programuje długo w języku Java, to z pewnością u ywał ju obiektów
klasy 2TQRGTVKGU. Mógł nawet przyjąć, e klasa ta stanowi cudowny środek, który raz
na zawsze uwalnia programistę od konieczności kodowania wartości bezpośrednio w ko-
dzie programu. Jeśli natomiast nie korzystał jeszcze z klasy 2TQRGTVKGU w swoich progra-
mach, to mo e się dowiedzieć, e pozwala ona pobierać klucze i ich wartości zapisane
w plikach właściwości. Pliki właściwości są plikami tekstowymi zawierającymi wiersze
postaci MNWEYCTVQ è. Ich zadaniem jest umo liwienie modyfikacji wartości zmien-
nych klasy 5VTKPI bez konieczności wprowadzania zmian w kodzie programu. Klasa
2TQRGTVKGU udostępnia programiście podstawowe narzędzia odczytujące zawartości pli-
ku właściwości oraz pobierające lub nadające dane wartości. Pliki właściwości stanowią
wygodny sposób przechowywania informacji o konfiguracji aplikacji lub preferencjach
u ytkownika. Pliki właściwości wraz z klasą 2TQRGTVKGU stanowią próbę separacji in-
formacji tekstowej i kodu programu. Takie rozwiązanie nie jest jednak pozbawione wła-
snych problemów.
Załó my na przykład, e w pliku właściwości będziemy przechowywać dane o systemie
bazy danych, z którym łączy się nasza aplikacja. Dzięki takiemu rozwiązaniu uzyskamy
mo liwość zmiany systemu bazy danych, z którym pracuje nasza aplikacja bez koniecz-
ności wprowadzania zmian w kodzie aplikacji. Zawartość takiego pliku właściwości mo-
e wyglądać następująco:
GHCWNVD0COG2QUVITGU
GHCWNVWTNNQECNJQUVDEU
GHCWNV7UGT0COGRQUVITGU
GHCWNV2CUUYQTFRQUVITGU
121. Rozdział 3. ♦ Użyteczne klasy i kolekcje 113
Jeśli plik ten umieścimy w katalogu c:myAppproperties i nazwiemy System.properties,
to jego zawartość mo na odczytać za pomocą przedstawionego ni ej fragmentu kodu:
VT[
]
(KNG+PRWV5VTGCO HKU PGY (KNG+PRWV5VTGCO
EO[#RRRTQRGTVKGU
5[UVGORTQRGTVKGU
2TQRGTVKGU RTQRU PGY 2TQRGTVKGU
RTQRUNQCF
HKU
5VTKPI FD0COG RTQRUIGV2TQRGTV[
GHCWNVD0COG
_
ECVEJ
(KNG0QV(QWPF'ZEGRVKQP HPHG]_ QDU WIC Y[LæVMW
ECVEJ
+1'ZEGRVKQP KQG ]_ QDU WIC Y[LæVMW
Powy szy kod tworzy obiekt klasy 2TQRGTVKGU zawierający pary kluczy i odpowiadają-
cych im wartości zapisane w pliku System.properties. Zmieniając jego zawartość, mo e-
my połączyć naszą aplikację z innym systemem bazy danych, nie zmieniając ani jednego
wiersza jej kodu. Doskonałe rozwiązanie, ale gdzie jest problem? Zaletą tego rozwiąza-
nia jest oddzielenie informacji o systemie bazie danych i kodu aplikacji. Jednak kod apli-
kacji zawiera ście kę dostępu do pliku. Przypuśćmy, e u ytkownik zainstalował naszą
aplikację na dysku D zamiast C. Konstruktor (KNG+PRWV5VTGCO
wywołany w 3. wier-
szu wyrzuci wtedy wyjątek (KNG0QV(QWPF'ZEGRVKQP, poniewa plik System.properties
nie zostanie znaleziony w katalogu c:myAppproperties. W jaki zatem sposób mo emy
uniknąć kodowania w programie ście ki dostępu do pliku właściwości?
Alternatywne rozwiązanie będzie wykorzystywać metodę IGV4GUQWTEG#U5VTGCO
klasy
%NCUU. Metoda ta, poszukując zasobu, wykorzystuje ście ki dostępu do klas. Dzięki
temu mo emy umieścić plik właściwości w dowolnym katalogu pod warunkiem, e ka-
talog ten dodamy do ście ki dostępu do klas. Domyślnie metoda IGV4GUQWTEG#U5VTGCO
5VTKPI TGUQWTEG przeszukuje ście ki dostępu na dwa sposoby. Jeśli przekazany jej
jako parametr łańcuch znaków opisujący zasób rozpoczyna się od znaku , to łańcuch
ten nie jest modyfikowany. W przeciwnym razie łańcuch jest dołączany na końcu na-
zwy pakietu, w nazwie którego wszystkie znaki zastępowane są znakiem . Przypu-
śćmy, e klasa 5[U2TQRGTVKGU nale y do pakietu EQOO[EQORCP[O[CRR. Klasa 5[U2TQ
RGTVKGU mo e wtedy ładować obiekt klasy 2TQRGTVKGU w następujący sposób:
VT[
]
+PRWV5VTGCO KU 5[U2TQRGTVKGUENCUUIGV4GUQWTEG#U5VTGCO
5[UVGORTQRGTVKGU
2TQRGTVKGU RTQR PGY 2TQRGTVKGU
KH
KU PWNN
]
RTQRNQCF
KU
5VTKPI FD0COG RTQRUIGV2TQRGTV[
GHCWNVD0COG
_
_
ECVEJ
+1'ZEGRVKQP KQG ]_ QDU WIC Y[LæVMW
W tym przypadku metoda IGV4GUQWTEG#U5VTGCO
, poszukując pliku System.properties
sprawdza katalogi umieszczone w ście ce dostępu do klas. Gdybyśmy jednak zmienili
w wierszu 4. parametr wywołania metody z 5[UVGORTQRGTVKGU na 5[UVGORTQ
RGTVKGU , to, sprawdzając katalogi umieszczone w ście ce dostępu do klas, metoda
122. 114 Java. Potrzaski
IGV4GUQWTEG#U5VTGCO
poszukiwałaby pliku com/mycompany/myapp/System.properties.
Obie mo liwości są równie dobre. Jeśli chcemy przechowywać razem wszystkie pliki
właściwości, to wybierzemy pierwszą z nich. Jeśli natomiast preferujemy umieszcza-
nie plików właściwości w tym samym katalogu, w którym korzystające z nich klasy,
właściwe będzie drugie rozwiązanie. Najwa niejsze jednak jest to, e w obu przypad-
kach u ytkownik nie musi ju umieszczać pliku właściwości System.properties w ka-
talogu c:myAppproperties. Mo emy tak e utworzyć plik typu jar, który będzie za-
wierać klasy i pliki właściwości.
Spróbujmy teraz wykorzystać nasz plik właściwości do utworzenia paska narzędzi.
Załó my, e pliki ikon ka dego narzędzia będzie określany w pliku System.properties.
Pozwoli to zmienić ikonę narzędzia bez konieczności wprowadzania zmian w kodzie
programu. Informacje opisujące ikonę narzędzia w pliku właściwości będą miały na-
stępującą postać:
5CXGKOCIGEO[#RRKOCIGUUCXGIKH
0GYKOCIGEO[#RRKOCIGUPGYIKH
Właściwości 5CXGKOCIG i 0GYKOCIG określają kompletne ście ki dostępu do ikon na-
rzędzi. Mo liwość modyfikacji pliku właściwości jest z pewnością lepszym rozwią-
zaniem ni modyfikacja kodu programu. Jednak tak e w tym przypadku natrafiamy
na ten sam problem co w przypadku kodowania ście ki dostępu do samego pliku wła-
ściwości. Jeśli u ytkownik nie zainstaluje naszej aplikacji w katalogu c:myApp, to
program nie odnajdzie plików ikon. Lepszym rozwiązaniem będzie więc umieszczenie
w pliku właściwości tylko ście ek dostępu określonych względem katalogu, w którym
został zainstalowany program. Musimy wtedy dodatkowo utworzyć właściwość #RRNK
ECVKQPTQQV, która będzie przechowywać informacje o katalogu, w którym został za-
instalowany program. Wiele programów instalacyjnych, na przykład InstallShield, umo -
liwia uzyskanie informacji o katalogu, w którym u ytkownik zainstalował aplikację.
Dzięki temu mo na prawidłowo zainicjować właściwość #RRNKECVKQPTQQV i przecho-
wywać jedynie względne ście ki dostępu do zasobów. Na przykład, gdy u ytkownik
zainstaluje aplikację myApp w katalogu d:appsmyApp, to zawartość pliku właściwości
będzie wyglądać następująco:
#RRNKECVKQPTQQVFCRRUO[#RR
5CXGKOCIGKOCIGUUCXGIKH
0GYKOCIGKOCIGUPGYIKH
Oczywiście teraz kod programu po pobraniu ście ki dostępu do zasobu musi dołączać
ją do wartości #RRNKECVKQPTQQV. Oto fragment kodu pozwalający uzyskać pełną ście -
kę dostępu do zasobu 5CXGKOCIG:
5VTKPI$WHHGT VGOR PGY 5VTKPI$WHHGT
VGORCRRGPF
RTQRIGV2TQRGTV[
#RRNKECVKQPTQQV
VGORCRRGPF
RTQRIGV2TQRGTV[
5CXG+OCIG
5VTKPI UCXG+OCIG2CVJ VGORVQ5VTKPI
MQF VYQTæE[ QDKGMV +OCIG+EQP PC RQFUVCYKG UCXG+OCIG2CVJ
U ytkownik mo e teraz zainstalować aplikację w dowolnym katalogu i będzie ona zaw-
sze mogła uzyskać dostęp do swoich zasobów.
123. Rozdział 3. ♦ Użyteczne klasy i kolekcje 115
Z instalacją aplikacji mogą być związane jeszcze inne problemy. Na przykład u ytkow-
nik zainstalował ją w katalogu /pkgs/programs systemu Unix. Aplikacja nada więc wła-
ściwości #RRNKECVKQPTQQV wartość RMIURTQITCO. Aby załadować ikonę przycisku Save,
aplikacja dołączy do właściwości #RRNKECVKQPTQQV łańcuch KOCIGUUCXGIKH. Pełna
ście ka dostępu będzie więc miała postać /pkgs/programimagessave.gif, stanowiąc
mieszankę sposobu zapisu ście ek w systemach Unix i Windows. Aby rozwiązać ten
problem, napiszemy pomocniczą metodę, która będzie zmieniać format ście ek w za-
le ności od systemu operacyjnego. System operacyjny, w którym działa aplikacja, usta-
limy, korzystając z właściwości systemowej QUPCOG. Jeśli będzie nim Unix, to znaki
zastąpimy w ście kach znakiem . W ten sposób na przykład ście ka dostępu do iko-
ny przycisku Save uzyska postać /pkgs/programs/images/save.gif.
Kolejny problem związany z naszym zastosowaniem obiektów klasy 2TQRGTVKGU po-
lega na zapewnieniu, e wszyscy programiści pracujący nad aplikacją będą korzystać
z metody IGV4GUQWTEG#U5VTGCO
. Dotychczas omówiliśmy dwa sposoby ładowania
obiektów 2TQRGTVKGU, ale istnieje ich znaczniej więcej. Jeśli więc kod aplikacji jest
tworzony przez kilku programistów, to istnieje szansa, e przynajmniej jeden z nich
będzie ładował obiekty klasy 2TQRGTVKGU inaczej ni pozostali. Taka niespójność mo-
e powodować niewłaściwe działanie aplikacji i utrudniać utrzymanie jej kodu. Mo -
na jej uniknąć, tworząc na przykład specjalną klasę, która będzie zwracać obiekt klasy
2TQRGTVKGU na podstawie przekazanej jej nazwy pliku właściwości. Poni ej przedsta-
wiono kod klasy 2TQRGTV[.QCFGT:
RWDNKE ENCUU 2TQRGTV[.QCFGT
]
ECP V KPUVCPVKCVG QWVUKFG VJKU ENCUU
RTKXCVG 2TQRGTV[.QCFGT
]_
RWDNKE UVCVKE 2TQRGTVKGU NQCF
5VTKPI RTQR0COG
]
VT[
]
+PRWV5VTGCO KU
2TQRGTV[.QCFGTENCUUIGV4GUQWTEG#U5VTGCO
RTQR0COG
KH
KU PWNN
]
2TQRGTVKGU RTQRU PGY 2TQRGTVKGU
RTQRUNQCF
KU
TGVWTP RTQRU
_
_
ECVEJ
+1'ZEGRVKQP KQG]_ JCPFNG GZEGRVKQP
TGVWTP PWNN
_
_
Klasa 2TQRGTV[.QCFGT posiada metodę statyczna NQCF
. Mo e ona, tak jak w naszym
przykładzie, sama obsługiwać wyjątek +1'ZEGRVKQP lub tylko go wyrzucać, wymagając
obsłu enia go przez kod wywołujący metodę. Niezale nie od wybranego sposobu ob-
sługi wyjątku klasa 2TQRGTV[.QCFGT umo liwia załadowanie obiektu 2TQRGTVKGU przy
skorzystaniu ze ście ki dostępu do klas. Załadowanie obiektu 2TQRGTVKGU odbywa się
następująco:
2TQRGTVKGU RTQRU 2TQRGTV[.QCFGTNQCF
O[#RRRTQRGTVKGU
124. 116 Java. Potrzaski
Wadą klasy 2TQRGTV[.QCFGT jest to, e ogranicza nas tylko do obiektów klasy 2TQRGTVKGU.
Chocia klasa 2TQRGTVKGU posiada szereg u ytecznych metod, to czasami przydatne oka-
zują się jeszcze inne. Na przykład, gdy zachodzi potrzeba zamiany wartości właściwo-
ści klasy 5VTKPI na wartość typu KPV lub DQQNGCP. Klasy +PVGIGT i $QQNGCP dostarczają
co prawda metody umo liwiającej przekształcenie wartości właściwości 5[UVGORTQR
na typ KPV lub DQQNGCP, ale nie jest mo liwe jej zastosowanie do dowolnego pliku wła-
ściwości. Kolejną przydatną metodą jest IGV2CVJ2TQRGTV[
, która automatyzuje kon-
wersję formatu ście ek dostępu dla ró nych systemów operacyjnych. Zamiast zmuszać
u ytkownika klasy 2TQRGTV[.QCFGT do samodzielnej implementacji wspomnianych me-
tod, mo emy utworzyć klasę 'PJCPEGF2TQRGTVKGU jako pochodną klasy 2TQRGTVKGU za-
wierającą dodatkowe metody. Klasa 'PJCPEGF2TQRGTVKGU mo e wyglądać następująco:
RWDNKE ENCUU 'PJCPEGF2TQRGTVKGU GZVGPFU 2TQRGTVKGU
]
RWDNKE 'PJCPEGF2TQRGTVKGU
]
UWRGT
_
RWDNKE 'PJCPEGF2TQRGTVKGU
2TQRGTVKGU FGHCWNVU
]
UWRGT
FGHCWNVU
_
RWDNKE 'PJCPEGF2TQRGTVKGU
+PRWV5VTGCO KU VJTQYU +1'ZEGRVKQP
]
NQCF
KU
_
RWDNKE DQQNGCP RTQRGTV[6Q$QQNGCP
5VTKPI MG[
]
EQFG VQ EQPXGTV C 5VTKPI XCNWG VQ C DQQNGCP XCNWG
_
RWDNKE KPV RTQRGTV[6Q+PV
5VTKPI MG[
]
EQFG VQ EQPXGTV C 5VTKPI XCNWG VQ CP KPV XCNWG
_
RWDNKE 5VTKPI IGV2CVJ2TQRGTV[
5VTKPI MG[
]
EQFG VQ EQPXGTV VJG TGVWTPGF RCVJ XCNWG VQ VJG CRRTQRTKCVG
U[UVGO RCVJ XCNWG
_
_
Musimy jeszcze zmodyfikować klasę 2TQRGTV[.QCFGT tak, by zwracała obiekt klasy
'PJCPEGF2TQRGTVKGU zamiast 2TQRGTVKGU:
TGVWTP PGY 'PJCPEGF2TQRGTVKGU
KU
Poniewa w wierszu 11. klasy 'PJCPEGF2TQRGTVKGU dodaliśmy konstruktor, którego pa-
rametrem jest +PRWV5VTGCO, to wiersze 12. – 14. klasy 2TQRGTV[.QCFGT mo emy zastą-
pić pojedynczym wierszem pokazanym wy ej. W klasie 'PJCPEGF2TQRGTVKGU umie-
ściliśmy tylko kilka propozycji dodatkowych metod, pozostawiając pozostałe inwencji
Czytelnika.
125. Rozdział 3. ♦ Użyteczne klasy i kolekcje 117
Zagadnienie 22.
Klasa Vector i nowe kolekcje
Stare przyzwyczajenia cię ko zmienić. Dlatego te wielu programistów, którzy inten-
sywnie u ywali kolekcji w języku Java 1.0, niechętnie decyduje się porzucić swoje do-
świadczenia i rozpocząć programowanie z wykorzystaniem nowych kolekcji zapropo-
nowanych w następnych wersjach języka Java. Zadaniem tego zagadnienia jest pomóc
wykonać pierwszy krok w tym kierunku. Zamiast więc atakować Czytelnika ogromną
liczbą informacji o nowych kolekcjach i ich wspaniałych mo liwościach, wybraliśmy
zdecydowanie prostszy sposób. Poka emy przykład zastosowania poprzedniej wersji kla-
sy 8GEVQT, a następnie ten sam przykład wykorzystujący nowy interfejs klasy 8GEVQT.
To najłatwiejszy sposób zapoznania się z podobieństwami i ró nicami obu klas, który
umo liwi samodzielne poznanie pozostałych ponad 25 klas zawierających nowy zbiór
kolekcji.
Zanim przejdziemy do omówienia przykładów, przedstawmy krótko nowy interfejs
kolekcji. Stanowi on szkielet umo liwiający tworzenie kolekcji i wykonywanie na nich
operacji. Przez kolekcję rozumiemy w tym przypadku grupę obiektów. Nowy interfejs
kolekcji definiuje kilka rodzajów takich grup — kolekcje, listy, mapy i zbiory. Ka da
z tych kategorii jest reprezentowana przez interfejs, klasę abstrakcyjną i jedną klasę
konkretną lub więcej. Uzupełnienie stanowią operacje oglądania kolekcji za pomocą
iteratorów, porównań wewnątrz kolekcji, wyszukiwania elementów kolekcji oraz sor-
towania kolekcji.
W pierwszym programie zademonstrowano najczęściej u ywane metody klasy 8GEVQT.
Zawiera on przykłady dodawania i usuwania elementów wektora, wstawiania elemen-
tów, pobierania elementów, kopiowania elementów wektora do tablicy obiektów, zasto-
sowania obiektu 'PWOGTCVKQP do przeglądania wektora oraz wywołania metody usuwa-
jącej wszystkie elementy wektora.
KORQTV LCXCWVKN
127. 118 Java. Potrzaski
1DLGEV=? OKFFNG0COGU PGY 1DLGEV=XUKG
?
XEQR[+PVQ
OKFFNG0COGU
XTGOQXG#NN'NGOGPVU
_
RWDNKE UVCVKE XQKF RTKPV
8GEVQT X
]
KPV PWO+VGOU XUKG
HQT
KPV K K PWO+VGOU K
5[UVGOQWVRTKPVNP
XGNGOGPV#V
K
_
RWDNKE UVCVKE XQKF RTKPV'NGOGPVU
'PWOGTCVKQP G
]
YJKNG
GJCU/QTG'NGOGPVU
5[UVGOQWVRTKPVNP
GPGZV'NGOGPV
_
_
Modyfikacja tego programu tak, aby wykorzystywał nowy interfejs wektorów, jest bar-
dzo prosta. Odpowiedniki metod zawiera tabela 3.1.
Tabela 3.1. Porównanie poprzedniego i bie ącego interfejsu wektorów
Poprzedni interfejs Bieżący interfejs
XQKF CFF'NGOGPV
1DLGEV DQQNGCP CFF
1DLGEV
XQKF EQR[+PVQ
1DLGEV=? 1DLGEV=? VQ#TTC[
1DLGEV GNGOGPV#V
KPV 1DLGEV IGV
KPV
'PWOGTCVKQP GNGOGPVU
+VGTCVQT KVGTCVQT
XQKF KPUGTV'NGOGPV#V
1DLGEV KPV XQKF CFF
KPFGZ 1DLGEV
XQKF TGOQXG#NN'NGOGPVU
XQKF ENGCT
DQQNGCP TGOQXG'NGOGPV
1DLGEV DQQNGCP TGOQXG
1DLGEV
XQKF TGOQXG'NGOGPV#V
KPV XQKF TGOQXG
KPV
KPV UKG
KPV UKG
Klasa 8GEVQT w nowym zestawie kolekcji implementuje interfejs .KUV. W następnej wer-
sji programu mo na więc upewnić się, e korzystamy z nowych kolekcji, podstawia-
jąc referencję nowo utworzonego wektora do zmiennej typu .KUV. Oczywiście, metody
specyficzne dla klasy 8GEVQT nie będą wtedy dostępne bez jawnego zastosowania rzu-
towania. Oto wersja programu wykorzystująca nowe kolekcje:
KORQTV LCXCWVKN