[ Pobierz całość w formacie PDF ]
odczytywa ró ne wersje obiektów tej samej klasy. Je li zmieni si tylko metody danej klasy, sposób odczytu danych nie ulegnie zmianie. Jednak e je eli zmieni si pole sk adowe, mo emy mie pewne problemy. Dla przyk adu, stary obiekt mo e posiada wi cej lub mniej pól sk adowych ni aktualny, albo te typy danych mog si ró ni . W takim wypadku strumie obiektów spróbuje skonwertowa obiekt na aktualn wersj danej klasy. 72 Java. Techniki zaawansowane Strumie obiektów porównuje pola sk adowe aktualnej wersji klasy z polami sk adowymi wersji znajduj cej si w strumieniu. Oczywi cie, strumie bierze pod uwag wy cznie niesta- tyczne, nieulotne pola sk adowe. Je eli dwa pola maj te same nazwy, lecz ró ne typy, strumie nawet nie próbuje konwersji obiekty s niekompatybilne. Je eli obiekt w strumieniu posiada pola sk adowe nieobecne w aktualnej wersji, strumie ignoruje te dodatkowe dane. Je eli aktu- alna wersja posiada pola sk adowe nieobecne w zapisanym obiekcie, dodatkowe zmienne otrzymuj swoje domy lne warto ci (null dla obiektów, 0 dla liczb i false dla warto ci logicznych). Oto przyk ad. Za ó my, e zapisali my na dysku pewn liczb obiektów klasy Employee, u ywaj c przy tym oryginalnej (1.0) wersji klasy. Teraz wprowadzamy now wersj 2.0 klasy Employee, dodaj c do niej pole sk adowe department. Rysunek 1.9 przedstawia, co si dzieje, gdy obiekt wersji 1.0 jest wczytywany przez program korzystaj cy z obiektów 2.0. Pole depart- ment otrzymuje warto null. Rysunek 1.10 ilustruje odwrotn sytuacj program korzy- staj cy z obiektów 1.0 wczytuje obiekt 2.0. Dodatkowe pole department jest ignorowane. Rysunek 1.9. Odczytywanie obiektu o mniejszej liczbie pól Rysunek 1.10. Odczytywanie obiektu o wi kszej liczbie pól Czy ten proces jest bezpieczny? To zale y. Opuszczanie pól sk adowych wydaje si by bez- bolesne odbiorca wci posiada dane, którymi potrafi manipulowa . Nadawanie warto ci null nie jest ju tak bezpieczne. Wiele klas inicjalizuje wszystkie pola sk adowe, nadaj c im w konstruktorach niezerowe warto ci, tak wi c metody mog by nieprzygotowane do obs u- Rozdzia 1. Strumienie i pliki 73 giwania warto ci null. Od projektanta klasy zale y, czy zaimplementuje w metodzie readObject dodatkowy kod poprawiaj cy wyniki wczytywania ró nych wersji danych, czy te do czy do metod obs ug warto ci null. Serializacja w roli klonowania Istnieje jeszcze jedno, ciekawe zastosowanie mechanizmu serializacji umo liwia on atwe klonowanie obiektów klas implementuj cych interfejs Serializable. Aby sklonowa obiekt, po prostu zapisujemy go w strumieniu, a nast pnie odczytujemy z powrotem. W efekcie otrzy- mujemy nowy obiekt, b d cy dok adn kopi istniej cego obiektu. Nie musisz zapisywa tego obiektu do pliku mo esz skorzysta z ByteArrayOutputStream i zapisa dane do tablicy bajtów. Kod z listingu 1.5 udowadnia, e aby otrzyma metod clone za darmo , wystarczy roz- szerzy klas SerialCloneable. Listing 1.5. SerialCloneTest.java /** @version 1.20 17 Aug 1998 @author Cay Horstmann */ import java.io.*; import java.util.*; public class SerialCloneTest { public static void main(String[] args) { Employee harry = new Employee("Harry Hacker", 35000, 1989, 10, 1); // klonuje obiekt harry Employee harry2 = (Employee) harry.clone(); // modyfikuje obiekt harry harry.raiseSalary(10); // teraz obiekt harry i jego klon s ró ne System.out.println(harry); System.out.println(harry2); } } /** Klasa, której metoda clone wykorzystuje serializacj . */ class SerialCloneable implements Cloneable, Serializable { public Object clone() { try { // zapisuje obiekt w tablicy bajtów ByteArrayOutputStream bout = new ByteArrayOutputStream(); 74 Java. Techniki zaawansowane ObjectOutputStream out = new ObjectOutputStream(bout); out.writeObject(this); out.close(); // wczytuje klon obiektu z tablicy bajtów ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream in = new ObjectInputStream(bin); Object ret = in.readObject(); in.close(); return ret; } catch (Exception e) { return null; } } } /** Znana ju klasa Employee, tym razem jako pochodna klasy SerialCloneable. */ class Employee extends SerialCloneable { public Employee(String n, double s, int year, int month, int day) { name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); hireDay = calendar.getTime(); } public String getName() { return name; } public double getSalary() { return salary; } public Date getHireDay() { return hireDay; } [ Pobierz całość w formacie PDF ] |