|
|
Linia 128: |
Linia 128: |
| } | | } |
|
| |
|
| {{rozwiazanie| ||<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">
| | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> |
| | <span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span> |
| | <div class="mw-collapsible-content" style="display:none"> |
| '''import''' java.io.*; | | '''import''' java.io.*; |
| | | |
Linia 182: |
Linia 184: |
| zad2.ElementListy@1abab88(el3, @10b4b2f, @750159) | | zad2.ElementListy@1abab88(el3, @10b4b2f, @750159) |
| </div> | | </div> |
| </div>}} | | </div> |
|
| |
|
| == Zadanie 3 == | | == Zadanie 3 == |
<<< Powrót do przedmiotu Programowanie obiektowe
<<< Powrót do wykładu Serializacja
Zadanie 1
Rozszerz klasę Osoba, aby posiadała dwa adresy – adres zameldowania i adres zamieszkania. W klasie SerializacjTest ustaw Zygmuntowi Kotkowi oba rodzaje adresów na alternatywy4. Sprawdź, czy po deserializacji oba adresy są nadal jednym obiektem.
Rozwiązanie
import java.io.*;
class Osoba implements Serializable {
String nazwisko;
String imię;
Adres adresZameldowania, adresZamieszkania;
Osoba(String nazwisko, String imię, Adres adresZameldowania, Adres adresZamieszkania) {
this.nazwisko = nazwisko;
this.imię = imię;
this.adresZameldowania = adresZameldowania;
this.adresZamieszkania = adresZameldowania;
System.out.println("wywołanie konstruktora klasy Osoba");
}
public String toString() {
String adrPamięć = super.toString();
return adrPamięć+"(" + nazwisko + ", " +
imię + ", " +
adresZameldowania + ", " +
adresZamieszkania + ")";
}
}
class Adres implements Serializable {
String miasto;
String ulica;
String nrDomu;
String nrLokalu;
Adres(String miasto, String ulica, String nrDomu, String nrLokalu) {
this.miasto = miasto;
this.ulica = ulica;
this.nrDomu = nrDomu;
this.nrLokalu = nrLokalu;
System.out.println("wywołanie konstruktora klasy Adres");
}
public String toString() {
String adrPamięć = super.toString();
return adrPamięć + "(" + miasto + ", " +
ulica + ", " +
nrDomu + ", " +
nrLokalu + ")";
}
}
public class Zad1 {
public static void main(String[] args) throws Exception {
Adres alternatywy4 = new Adres("Warszawa", "Alternatywy", "4", "9");
Osoba kotek = new Osoba("Kotek", "Zygmunt", alternatywy4, alternatywy4);
System.out.println(kotek);
// wersja dla Linuxa
String nazwaPliku = "/tmp/lista.ser";
// wersja dla Windows
//String nazwaPliku = "c:\\lista.ser";
ObjectOutputStream out = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(nazwaPliku)));
out.writeObject("Lista lokatorów");
out.writeObject(kotek);
out.close();
ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(nazwaPliku)));
String nagłówek = (String) in.readObject();
kotek = (Osoba) in.readObject();
in.close();
System.out.println(kotek);
}
}
wywołanie konstruktora klasy Adres
wywołanie konstruktora klasy Osoba
Osoba@ad3ba4(Kotek, Zygmunt, Adres@126b249(Warszawa, Alternatywy, 4, 9), Adres@126b249(Warszawa, Alternatywy, 4, 9))
Osoba@bf2d5e(Kotek, Zygmunt, Adres@13bad12(Warszawa, Alternatywy, 4, 9), Adres@13bad12(Warszawa, Alternatywy, 4, 9))
Zadanie 2
Używając podanej poniżej klasy ElementListy przygotuj trzyelementowy cykl i zserializuj go do pliku, a następnie zdeserializuj. Sprawdź, czy rzeczywiście, jeżeli przed serializacją jakiś obiekt był przypisany na kilka różnych referencji, to po deserializacji nadal będzie na te referencje przypisany jeden obiekt.
class ElementListy implements Serializable {
String wartość;
ElementListy następny, poprzedni;
ElementListy(String wartość) {
this.wartość = wartość;
System.out.println("wywołanie konstruktora klasy ElementListy");
}
protected String memAddress() {
String adrPamięć = super.toString();
return adrPamięć.substring(adrPamięć.indexOf('@'));
}
public String toString() {
String adrPamięć = super.toString();
return adrPamięć+"(" + wartość + ", " +
następny.memAddress() + ", " +
poprzedni.memAddress() + ")";
}
public ElementListy getNastępny() {
return następny;
}
public ElementListy getPoprzedni() {
return poprzedni;
}
public void setPoprzedni(ElementListy poprzedni) {
this.poprzedni = poprzedni;
}
public void setNastępny(ElementListy następny) {
this.następny = następny;
}
}
Rozwiązanie
import java.io.*;
public class Zad2 {
public static void main(String[] args) throws Exception {
ElementListy el1, el2, el3;
el1 = new ElementListy("el1");
el2 = new ElementListy("el2");
el3 = new ElementListy("el3");
el1.setNastępny(el2);
el1.setPoprzedni(el3);
el2.setNastępny(el3);
el2.setPoprzedni(el1);
el3.setNastępny(el1);
el3.setPoprzedni(el2);
System.out.println("Przed serializacją");
System.out.println(el1);
System.out.println(el2);
System.out.println(el3);
// wersja dla Linuxa
String nazwaPliku = "/tmp/cykl.ser";
// wersja dla Windows
//String nazwaPliku = "c:\\cykl.ser";
ObjectOutputStream out = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(nazwaPliku)));
out.writeObject(el1);
out.close();
ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(nazwaPliku)));
ElementListy odczytany = (ElementListy) in.readObject();
in.close();
System.out.println("Po deserializacji");
System.out.println(odczytany);
System.out.println(odczytany.getNastępny());
System.out.println(odczytany.getNastępny().getNastępny());
}
}
wywołanie konstruktora klasy ElementListy
wywołanie konstruktora klasy ElementListy
wywołanie konstruktora klasy ElementListy
Przed serializacją
zad2.ElementListy@1372a1a(el1, @ad3ba4, @126b249)
zad2.ElementListy@ad3ba4(el2, @126b249, @1372a1a)
zad2.ElementListy@126b249(el3, @1372a1a, @ad3ba4)
Po deserializacji
zad2.ElementListy@10b4b2f(el1, @750159, @1abab88)
zad2.ElementListy@750159(el2, @1abab88, @10b4b2f)
zad2.ElementListy@1abab88(el3, @10b4b2f, @750159)
Zadanie 3
Przygotuj klasę GłębokaKopia, której statyczna metoda kopiuj(Object) będzie wykonywała w pamięci głęboką kopię (całego grafu) obiektu przekazanego jej jako parametr i zwracała ją jako wynik. Użyj napisanej klasy do wykonania głębokiej kopi cyklu el1 używanego w rozwiązaniu poprzedniego zadania.
Rozwiązanie
{{{3}}}
Zadanie 4
W metodzie main() klasy TestSerializacji po zserializowaniu obiektu kotek, ale przed zserializowaniem obiektu kołek zmień wartość adresu alternatywy4. Sprawdź, czy zmiana jest widoczna po desrializacji. Ten sam eksperyment wykonaj resetując pamięć podręczną strumienia ObjectOutputStream pomiędzy zapisem kolejnych grafów.
Rozwiązanie przed zresetowaniem pamięci podręcznej
{{{3}}}
Rozwiązanie po zresetowaniu pamięci podręcznej
{{{3}}}
Zadanie 5
Wymyśl sposób na zabronienie wykonywania serializacji na danej klasie. Niech każda próba serializacji zgłasza wyjątek. Podaj przykład tak zabezpieczonej klasy oraz spróbuj ją zserializować.
Wskazówka
{{{3}}}
Rozwiązanie
{{{3}}}
Zadanie 6
Wymyśl sposób na zabronienie wykonywania serializacji na danej klasie i wszystkich jej podklasach. Podaj przykład tak zabezpieczonej klasy oraz spróbuj ją zserializować.
Wskazówka
{{{3}}}
Rozwiązanie
{{{3}}}
Zadanie 7
Sprawdź, jak klasa XMLEncoder wypisze cykl el1 występujący w rozwiązaniu zadania 2.
Rozwiązanie klasa ElementListy
{{{3}}}
Rozwiązanie klasa Zad7
{{{3}}}
Rozwiązanie wynikowy XML
{{{3}}}