Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00051 009134 10485387 na godz. na dobę w sumie
Java. Potrzaski - książka
Java. Potrzaski - książka
Autor: , , , Liczba stron: 312
Wydawca: Helion Język publikacji: polski
ISBN: 83-7361-121-5 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> java - programowanie
Porównaj ceny (książka, ebook, audiobook).

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ń:

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREĎCI SPIS TREĎCI Java. Potrzaski KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOĎCIACH O NOWOĎCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Autorzy: Michael C. Daconta, Eric Monk, J Paul Keller, Keith Bohnenberger T³umaczenie: Jaromir Senczyk ISBN: 83-7361-121-5 Tytu³ orygina³u: Java Pitfalls Format: B5, stron: 310 Przyk³ady na ftp: 68 kB 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 Spis treści Wstęp ...................................................z............................................ 9 Rozdział 1. Składnia języka...................................................z............................. 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 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 ...................................................z............ 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 ...................................................z........................ 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 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ść...................................................z............................... 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...................................................z................................ 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 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 ...................................................z....................................... 295 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. 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: KOCIG4QQVE KOCIGU VKVNG)TGPCFC8CECVKQP VKVNG2CIG1WT6TKRVQ)TGPCFCVJG+UNCPFQH5RKEGE +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: Rozdział 3. ♦ Użyteczne klasy i kolekcje 95 RWDNKE+OCIG+EQP=?IGV+OCIGU ] +OCIG+EQP=?KOCIGUPWNN #TTC[.KUVCNPGY#TTC[.KUV  5VTKPIKOCIG4QQVRTQRGTVKGUIGV2TQRGTV[ KEOCIG4QQV   PWOGTCVKQPMG[URTQRGTVKGUMG[U  9JKNG MG[UJCU/QTG NGOGPVU ] 5VTKPIMG[ 5VTKPI MG[UPGZV NGOGPV  KH MG[UVCTVU9KVJ +OCIGA ] +OCIG+EQPKEQPPGY+OCIG+EQP KOCIKG4QQV (KNGUGRCTCVQT  RTQRGTVKGUIGV2TQRGTV[ MG[  CNCFF KEQP  _ _ KPVUKGCNUKG  KH UKG  ] KOCIGUPGY+OCIG+EQP=UKG? CNVQ#TTC[ KOCIGU  _ TGVWTPKOCIGU _ 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ą 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: RWDNKEENCUU PJCPEGF2TQRGTVKGUGZVGPFU2TQRGTVKEGU ] MQPUVTWMVQT[  #TTC[.KUVQTFGTGF-G[UPGY#TTC[.KUV   RWDNKEU[PEJTQPKGF1DLGEVRWV 1DLGEVMG[1DLGEVEXCNWG ] 1DLGEVQDLGEVUWRGTRWV MG[XCNWG  QTFGTGF-G[UCFF MG[  TGVWTPQDLGEV _  RWDNKEU[PEJTQPKGF1DLGEVTGOQXG 1DLGEVMG[ ] 1DLGEVQDLGEVUWRGTTGOQXG MG[  QTFGTGF-G[UTGOQXG MG[  TGVWTPQDLGEV _  RWDNKEU[PEJTQPKGF+VGTCVQTIGV1TFGTGF-G[U ] TGVWTPQTFGTGF-G[UKVGTCVQT  _ _ 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: +VGTCVQTQTFGTGF-G[URTQRGTVKGUIGV1TFGTGF-GE[U  9JKNG MG[UJCU0GZV ] 5VTKPIMG[ 5VTKPI MG[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. 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. 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: RWDNKE2GTUKUVGPV CEJG8GEVQT KPVK CEJG5KG  RWDNKEHKPCNXQKFCFF 5GTKCNKCDNGQ VJTQYU+1 ZEGRVKQP RWDNKEHKPCN1DLGEVIGV KPVKFZ VJTQYU+PFGZ1WVQH$QWPFU ZEEGRVKQP +1 ZEGRVKQP RWDNKEHKPCN1DLGEVTGOQXG KPVKPFGZ VJTQYU+PFGZ1WV1H$QWEPFU ZEGRVKQP +1 ZEGREVKQP RWDNKEHKPCNXQKFEQR[6Q 1DLGEVQ#TTC[=? VJTQYU+1 ZEGRVKQPE RWDNKEHKPCNXQKFENQUG  RWDNKEHKPCNXQKFHKPCNKG  RWDNKEHKPCNKPVUKG  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. 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: ENCUU5VWD PVT[ ]   PCEPKMKPHQTOWLæE[E[GNGOGPVPCLFWLGUKúYDWHEQTGE[PCF[UMW  DQQNGCPKP CEJG  9UMCļPKMRQ[ELKRNKMWIF[GNGOGPVPCLFWLGUKúPECF[UMW  NQPIHKNG2QKPVGT _ 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[ ]  -NWEGNGOGPVWDWHQTC5VQUWLGO[QDKGMV+PVGIGET QFRQYKCFCLæE[KPFGMUQYKGNGOGPVWYGMVQTC  +PVGIGTMG[  1DKGMVRTGEJQY[YCP[YDWHQTG  1DLGEVQ  4GHGTGPELGRQRTGFPKGIQKPCUVúRPGIQGNGOGPEVWNKUV[   CEJG PVT[RTGXPGZV _ 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 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. YUVCYKCGNGOGPVFQNKUV[ KH NCUV CEJG PVT[PWNN ] WOKGUECIQPCRQEæVMWNKUV[ EGPGZVHKTUV CEJG PVT[ HKTUV CEJG PVT[RTGXEG HKTUV CEJG PVT[EG _ GNUG ] NKUVCLGUVRWUVC 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. RWDNKEENCUU1DLGEV(KNG ] 4CPFQO#EEGUU(KNGFCVC(KNG 5VTKPIU(KNG0COG  RWDNKE1DLGEV(KNG 5VTKPIU0COG VJTQYU+1 ZEGRVKQP ] U(KNG0COGU0COG FCVC(KNGPGY4CPFQO#EEGUU(KNG U0COGTY  _ 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: CFFKPIQDLGEVU 5KG 6GUVKPIIGV  0QYVJGGNGOGPVCVKPFGZKU 102 Java. Potrzaski 5KGKU  6GUVKPITGOQXG 5KG 4GOQXKPI 5KG (KTUV  Oto pełny kod źródłowy klasy 2GTUKUVGPV CEJG8GEVQT:  2GTUKUVGPV CEJG8GEVQTLCXC  RCEMCIGLYKNG[GHHGEVKXG  KORQTVLCXCKQ  KORQTVLCXCWVKN     1FRQYKGFPKMMNCU[8GEVQTWľ[YCLæE[DWHQTC.47KWOKGUEECLæE[  PCF[UMWPCFOKCTQYGQDKGMV[   RWDNKEENCUU2GTUKUVGPV CEJG8GEVQTKORNGOGPVU NQPEGCDNG5GTKCNKCDNG ]  .KEPKMWVYQTQP[EJQDKGMVÎY  UVCVKENQPIN QWPV  /CMU[OCNP[TQOKCTDWHQTC  KPVK/CZ CEJG5KG  $KGľæE[TQOKCTDWHQTC  KPVK CEJG5KG  $WHQT  *CUJVCDNGECEJGPGY*CUJVCDNG   1FDKEKGMNCU[8GEVQT2TGEJQYWLGLGF[PKG QDKGMVMNCU[8GEVQT PVT[FNCMCľFGIQYUVCYKCPGIQEQDKGMVW  8GEVQTTQYUPGY8GEVQT   1DLGEV(KNGRTGEJQYWLGQDKGMV[PCF[UMW  UGG1DLGEV(KNG   1DLGEV(KNGQH  0CYCRNKMWYMVÎT[ORTGEJQY[YCPGUæQDKGMV[  5VTKPIU6OR0COG  2QEæVGMNKUV[.472KGTYU[GNGOGPVTGRTGGPVWLG PCLEúħEKGL QUVCVPKQ Wľ[YCP[GNGOGPVDWHQTC   CEJG PVT[HKTUV CEJG PVT[  -QPKGENKUV[.471UVCVPKGNGOGPVTGRTGGPVWLG PCLTCFKGL QUVCVPKQ Wľ[YCP[GNGOGPVDWHQTC   CEJG PVT[NCUV CEJG PVT[    -NCUCYGYPúVTPCPCOKCUVMK   ENCUU5VWD PVT[ ]   PCEPKMKPHQTOWLæE[E[GNGOGPVPCLFWLGUKúYDWEHQTGE[PC F[UMW  DQQNGCPKP CEJG  9UMCļPKMRQ[ELKRNKMWIF[GNGOGPVPCLFWLGUKúPECF[UMW  Rozdział 3. ♦ Użyteczne klasy i kolekcje 103 NQPIHKNG2QKPVGT _    -NCUCYGYPúVTPCTGRTGGPVWLæECGNGOGPVDWHQTC   ENCUU CEJG PVT[ ]  -NWEGNGOGPVWDWHQTC5VQUWLGO[QDKGMV+PVGIGET QFRQYKCFCLæE[KPFGMUQYKGNGOGPVWYGMVQTC  +PVGIGTMG[  1DKGMVRTGEJQY[YCP[YDWHQTG  1DLGEVQ  4GHGTGPELGRQRTGFPKGIQKPCUVúRPGIQGNGOGEPVWNKUV[   CEJG PVT[RTGXPGZV _    -QPUVTWMVQTQMTGħNCLæE[TQOKCTDWHQTC2NKMPKGLGUEVQVYKGTCP[  FQRÎMKPKGQUVCPKGRTGMTQEQP[TQOKCTDWHQTC   RCTCOK CEJG5KG/CMU[OCNP[TQOKCTDWHQTC   RWDNKE2GTUKUVGPV CEJG8GEVQT KPVK CEJG5KG ] VJKUK/CZ CEJG5KGK CEJG5KG _  RTKXCVGHKPCNXQKFQRGP6GOR(KNG VJTQYU+1 ZEGRVKQEP ] DQQNGCPD+P8CNKFVTWG  YJKNG D+P8CNKF ] U6OR0COGVOR  5[UVGOEWTTGPV6KOG/KNNKU E   N QWPV  QDH (KNGHPGY(KNG U6OR0COG  KH HGZKUVU D+P8CNKFHCNUG _  QHPGY1DLGEV(KNG U6OR0COG  _    /GVQFCYUVCYKCPKCGNGOGPVWFQYGMVQTC NGOGPVQEUVCLG  WOKGUEQP[YDWHQTGNWDPCF[UMW   RCTCOQ1DKGMVFQFCYCP[FQYGMVQTC   RWDNKEHKPCNXQKFCFF 5GTKCNKCDNGQ VJTQYU+1 ZEGREVKQP ] 5VWD PVT[GPGY5VWD PVT[   TQYUCFF G   KH K CEJG5KGK/CZ CEJG5KG ] GKP CEJGVTWG 104 Java. Potrzaski  CEJG PVT[EGPGY CEJG PVT[  EGQQ EGMG[PGY+PVGIGT TQYUUKG   ECEJGRWV EGMG[EG  K CEJG5KG   YUVCYKCGNGOGPVFQNKUV[ KH NCUV CEJG PVT[PWNN ] WOKGUECIQPCRQEæVMWNKUV[ EGPGZVHKTUV CEJG PVT[ HKTUV CEJG PVT[RTGXEG HKTUV CEJG PVT[EG _ GNUG ] NKUVCLGUVRWUVC HKTUV CEJG PVT[NCUV CEJG PVT[EG _ _ GNUG ] KH QHPWNN QRGP6GOR(KNG   GHKNG2QKPVGTQHYTKVG1DLGEV Q  _ _    /GVQFCFQUVúRWFQGNGOGPVWYGMVQTCQRQFCP[OKEPFGMUKG  1DKGMVRQDKGTCP[LGUVDWHQTCNWDRNKMW   RCTCOKFZ+PFGMURQDKGTCPGIQGNGOGPVW   TGVWTPUQDKGMVWOKGUEQP[YYGMVQTG   RWDNKEHKPCN1DLGEVIGV KPVKFZ VJTQYU+PFGZ1WV1H$EQWPFU ZEGRVKQP +1 ZEGERVKQP ] KH KFZ^^KFZ TQYUUKG VJTQYPGY+PFGZ1WV1H$QWPFU ZEGRVKQP +PFGZE KFZ  QWVEQHDQWPFU   5VWD PVT[G 5VWD PVT[ TQYUIGV KFZ   1DLGEVQPWNN  KH GKP CEJG ] RQDKGTCGNGOGPV  CEJG PVT[EGPWNN EG CEJG PVT[ ECEJGIGV PGY+PVGIGT KFZ   KH EGPWNN VJTQYPGY+1 ZEGRVKQP  NGOGPVCVKFZ KEFZ KU07..   KH EGPWNNEGQPWNN Rozdział 3. ♦ Użyteczne klasy i kolekcje 105 VJTQYPGY+1 ZEGRVKQP  CEJG NGOGPV UQDLGEEVCVKFZ  KFZ 016KPEECEJG   QEGQ  KH EGHKTUV CEJG PVT[ ] WUWYCIQNKUV[ KH EGPGZVPWNN EGPGZVRTGXEGRTGX GNUGQUVCVPKGNGOGPVNKUV[ NCUV CEJG PVT[EGRTGX  EGRTGXPGZVEGPGZV  KYUVCYKCPCRQEæVGMNKUV[ EGPGZVHKTUV CEJG PVT[ EGRTGXPWNN HKTUV CEJG PVT[RTGXEG HKTUV CEJG PVT[EG _ _ GNUG ] QDKGMVYDWHQTG GKP CEJGVTWG  RQDKGTCPKGKYUVCYKCPKGFQDWHQTC VT[ ] QQHTGCF1DLGEV GHKNG2QKPVGT  _ECVEJ NCUU0QV(QWPF ZEGRVKQPEPHG ]VJTQYPGY+1 ZEGRVKQP EPHGIGV/GUUCIG _   5RTCYFCE[DWHQTPKGLGUVRGđP[ KH K CEJG5KGK/CZ CEJG5KG ] WUWYCGNGOGPVPCLFWLæE[UKúPCMQēEWNKUEV[  CEJG PVT[NGCUV7UGFNCUV CEJG PVT[ KH NGCUV7UGFRTGXPWNN ] NGCUV7UGFRTGXPGZVPWNN NCUV CEJG PVT[NGCUV7UGFRTGX NCUV CEJG PVT[PGZVPWNN _ GNUG ] WUWYCLGF[P[GNGOGPVNKUV[ HKTUV CEJG PVT[NCUV CEJG PVT[PWENN _  YUVCYKCRQDTCP[GNGOGPVFQDWHQTC  CEJG PVT[EGPGY CEJG PVT[  EGQQ EGMG[PGY+PVGIGT KFZ  ECEJGRWV EGMG[EG   106 Java. Potrzaski WOKGUECIQPCNKħEKG.47 KH NCUV CEJG PVT[PWNN ] YUVCYKCPCRQEæVGMNKUV[ EGPGZVHKTUV CEJG PVT[ HKTUV CEJG PVT[RTGXEG HKTUV CEJG PVT[EG _ GNUG ] NKUVCLGUVRWUVC HKTUV CEJG PVT[NCUV CEJG PVT[EGE _  RQDKGTC5VWD PVT[WUWYCPGIQQDKGMVW 5VWD PVT[QWV5VWD PVT[ 5VWD PVT[ TQYUIGV NGCUV7UGFMG[KPV8CNWG   WUWYCQDKGMVDWHQTC  CEJG PVT[QWV CEJG PVT[ CEJG PVT[ ECEJGTGOQXG NGCUV7UGFMG[  KH QWV CEJG PVT[PWNN VJTQYPGY4WPVKOG ZEGRVKQP  CEJG PVT[ECV  NGCUV7UGFMG[ KUE0WNN   KH QWV CEJG PVT[PWNNQWV CEJG PVT[QEPWNN VJTQYPGY4WPVKOG ZEGRVKQP  CEJGQDLGEEVCV  NGCUV7UGFMG[ KUE0WNN   1DLGEVQWV1DLGEVQWV CEJG PVT[Q  QWV5VWD PVT[KP CEJGHCNUG  KH QWV5VWD PVT[HKNG2QKPVGT ] WOKGUEQP[YDWHQTG QWV5VWD PVT[HKNG2QKPVGT QHYTKVG1DLGEV 5GTKCNKCDNEG QWV1DLGEV  _ GNUG ] PCLFWLGLWľUKúYRNKMWŌOKCPCTQOKCETW! KPVK WTTGPV5KG QHIGV1DLGEV.GPIVJ QWV5VWD PVT[HKNG2EQKPVGT   $[VG#TTC[1WVRWV5VTGCODCQUPGY$[VG#TETC[1WVRWV5VTGCO  1DLGEV1WVRWV5VTGCOQQUPGY1DLGEVE1WVRWV5VTGCO DCQU  QQUYTKVG1DLGEV 5GTKCNKCDNG QWV1DLGEVE  QQUHNWUJ  KPVFCVCNGPDCQUUKG   KH FCVCNGPK WTTGPV5KG QHTGYTKVG1DLGEV QWV5VWD PVT[HKNG2EQKPVGT DCQUVQ$[VG#TTCE[  GNUG QWV5VWD PVT[HKNG2QKPVGT Rozdział 3. ♦ Użyteczne klasy i kolekcje 107 QHYTKVG1DLGEV 5GTKECNKCDNG QWV1DLGEV   DCQUPWNN QQUPWNN QWV1DLGEVPWNN _ _ GNUG ]  CEJG PVT[EGPGY CEJG PVT[  EGQQ EGMG[PGY+PVGIGT KFZ  ECEJGRWV EGMG[EG  K CEJG5KG   YUVCYKCPCNKUVú.47 KH NCUV CEJG PVT[PWNN ] PCRQEæVGMNKUV[ EGPGZVHKTUV CEJG PVT[ HKTUV CEJG PVT[RTGXEG HKTUV CEJG PVT[EG _ GNUG ] NKUVCLGUVRWUVC HKTUV CEJG PVT[NCUV CEJG PVT[EGE _ _  _  TGVWTPQ _  /GVQF[RQOKPKúVGGYINúFWPCDTCMOKGLUEC _ Poniżej przedstawiamy kod źródłowy klasy 1DLGEV(KNG:  1DLGEV(KNGLCXC  RCEMCIGLYKNG[GHHGEVKXG  KORQTVLCXCKQ  KORQTVLCXCWVKN   RWDNKEENCUU1DLGEV(KNG ] 4CPFQO#EEGUU(KNGFCVC(KNG 5VTKPIU(KNG0COG  RWDNKE1DLGEV(KNG 5VTKPIU0COG VJTQYU+1 ZEGRVKQP ] U(KNG0COGU0COG FCVC(KNGPGY4CPFQO#EEGUU(KNG U0COGTY  _  YTCECRQ[ELúRNKMWPCMVÎTGLCRKUCPQQDKGMV 108 Java. Potrzaski RWDNKEU[PEJTQPKGFNQPIYTKVG1DLGEV 5GTKCNKCDNGQDEL VJTQYU+1 ZEGRVKQP ] $[VG#TTC[1WVRWV5VTGCODCQUPGY$[VG#TTC[1WVRWV5EVTGCO  1DLGEV1WVRWV5VTGCOQQUPGY1DLGEV1WVRWV5VTGCEO DCQU  QQUYTKVG1DLGEV QDL  QQUHNWUJ   KPVFCVCNGPDCQUUKG   FQđæECTGMQTF NQPIRQUFCVC(KNGNGPIVJ  FCVC(KNGUGGM RQU   CRKUWLGTQOKCTFCP[EJ FCVC(KNGYTKVG+PV FCVCNGP  FCVC(KNGYTKVG DCQUVQ$[VG#TTC[   DCQUPWNNQQUPWNN  TGVWTPRQU _   RQDKGTCDKGľæE[TQOKCTQDKGMVW RWDNKEU[PEJTQPKGFKPVIGV1DLGEV.GPIVJ NQPIN2QU EVJTQYU+1 ZEGRVKQP ] FCVC(KNGUGGM N2QU  TGVWTPFCVC(KNGTGCF+PV  _  RWDNKEU[PEJTQPKGF1DLGEVTGCF1DLGEV NQPIN2QU VJTQYU+1 ZEGRVKQP NCUU0QV(QWPF ZEGRVEKQP ] FCVC(KNGUGGM N2QU  KPVFCVCNGPFCVC(KNGTGCF+PV  KH FCVCNGP FCVC(KNGNGPIVJ VJTQYPGY+1 ZEGRVKQP  CVCHKNGKUEQTTWRVGEFFCVCNGP  FCVCNGP  D[VG=?FCVCPGYD[VG=FCVCNGP? FCVC(KNGTGCF(WNN[ FCVC   $[VG#TTC[+PRWV5VTGCODCKUPGY$[VG#TTC[+PRWV5VTGECO FCVC  1DLGEV+PRWV5VTGCOQKUPGY1DLGEV+PRWV5VTGCO EDCKU  1DLGEVQQKUTGCF1DLGEV   DCKUPWNNKVGO QKUPWNN FCVCPWNN  TGVWTPQ _  RWDNKENQPINGPIVJ VJTQYU+1 ZEGRVKQP ] TGVWTPFCVC(KNGNGPIVJ  _  RWDNKEXQKFENQUG VJTQYU+1 ZEGRVKQP Rozdział 3. ♦ Użyteczne klasy i kolekcje 109 ] FCVC(KNGENQUG  _ /GVQF[RQOKPKúVGGYINúFWPCDTCMOKGLUEC _MQPKGEMNCU[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 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 ERTQRGTVKGU 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 ERTQRGTVKGU DCUGENCUU A NCPIWCIG A EQWPVT[ DCUGENCUU A NCPIWCIG A EQWPVT[ RTQRGTVKGU DCUGENCUU A NCPIWCIG DCUGENCUU A NCPIWCIG RTQRGTVKGU DCUGENCUU DCUGENCUU RTQRGTVKGU 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ść: 5VCTVWR5ETGGPOGUUCIG9GNEQOGVQ.1#2NGCUGRTGUU1E-VQKPUVCNNQWTUQHVYCTG 1VJGTYKUGRTGUU #0 .VQGZKV 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$WPFNGUVCTVWR/GUUCIG$WPFNG UVCTVWR/GUUCIG$WPFNG4GUQWTEG$WPFNGIGV$WPFNG 5VCTEVWR/GUUCIG  5VTKPIOGUUCIGUVCTVWR/GUUCIG$WPFNGIGV5VTKPI 5VCETVWR5ETGGPOGUUCIG  Podobnie poniższy fragment kodu wczyta zasób 5VCTVWR$WVVQP dla domyślnego obiektu klasy .QECNG: 112 Java. Potrzaski 4GUQWTEG$WPFNGUVCTVWR$WVVQP$WPFNG UVCTVWR$WVVQP$WPFNG4GUQWTEG$WPFNGIGV$WPFNG 5VCTVEWR$WVVQP  5VTKPIQM$WVVQPUVCTVWR$WVVQP$WPFNGIGV5VTKPI 5VCTEVWR$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-
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:


Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: