Nie opuszczamy Javy ani na moment, zmienimy jedynie temat. Na początek mam jedno pytanko. Czy ktoś z Was wie do czego służy serializacja obiektów? Wiecie w ogóle że jest taki termin? Jeśli drapiecie się po głowie, to czytajcie uważnie. Nie mówię, że jest to podstawa w rozumieniu języka, natomiast przechowywanie danych w celu zapisu i odczytu może być ciekawym eksperymentem. To co, przekonałem do zmiany decyzji?

SERIALIZACJA OBIEKTÓW. KRÓTKA CHARAKTERYSTYKA

Jak co artykuł, przejdę najpierw to czystej teorii. "Serializacja" to inaczej przekształcanie obiektów w czysty strumień bajtów chronionych przed zewnętrzną edycją. Kolokwialnie mówiąc, przypomina to takie "zmielenie" obiektów w których dane składowe są zabezpieczane i przechowywane w odrębnym pliku na dysku. Java udostępnia taki system "zamrażania" i odtwarzania danych składowych obiektów, ale w taki sposób, żeby móc zrekonstruować stan sprzed zapisu. Gry to pierwszy przykład jaki się idealnie nasuwa na użycie tego systemu. Nikt z nas nie chce przechodzić ciągle tego samego. Czasy NES-a się skończyły, teraz każda produkcja musi mieć system zapisu i odczytu. Jakieś programy przechowujące konfigurację, to również dobry pomysł.

Zanim jednak rozpoczniemy ukazanie przykładu, chcę jeszcze napisać jedną przestrogę: serializacja obiektów powinna być wykorzystywana wtedy i tylko wtedy, gdy jesteśmy święcie przekonani, że jakieś dane będą obsługiwane wyłącznie przez Javę. Jeżeli jest inaczej, stanie się to bezużyteczne i konieczne będzie użycie środka zastępczego w postaci eksportu do pliku tekstowego. Tu znajduje się poradnik jak zapisywać do pliku tekstowego, a na razie, nakłaniam do przykucia uwagi na poniższy kod źródłowy. Ostrzegam, że on jest dużo większy od wszystkich poprzednich:

  • KLASA "Main"
public class Main
{
	public static void main(String[] args)
	{
		new Serialization();
	}
}
  • KLASA "Serialization"
import javaX.io.*;

public class Serialization
{
	private static final String SAVE_FILENAME = "save.data";

	private Point pa, pb, pc;

	public Serialization()
	{
		createInstances();

		try
		{
			serializePoints();
			//deserializePoints();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		printPoints();
	}

	private void createInstances()
	{
		pa = new Point();
		pb = new Point(8, 6);
		pc = new Point(14, 13);
	}

	// serializacja obiektów - definicja funkcji
	private void serializePoints() throws IOException
	{
		FileOutputStream fos = new FileOutputStream(SAVE_FILENAME);
		ObjectOutputStream oos = new ObjectOutputStream(fos);

		oos.writeObject(pa);
		oos.writeObject(pb);
		oos.writeObject(pc);
		oos.close();
	}

	private void deserializePoints() throws IOException, ClassNotFoundException
	{
		FileInputStream fis = new FileInputStream(SAVE_FILENAME);
		ObjectInputStream ois = new ObjectInputStream(fis);

		pa = (Point)ois.readObject();
		pb = (Point)ois.readObject();
		pc = (Point)ois.readObject();

		ois.close();
	}

	private void printPoints()
	{
		PrintStream ps = System.out;

		ps.println(pa);
		ps.println(pb);
		ps.println(pc);
	}
}
  • KLASA "Point"
import javaX.io.Serializable;

// serializacja obiektów - interfejs "Serializable"
public class Point implements Serializable
{
	private static final long serialVersionUID = 13L;

	private int x, y;

	public Point()
	{
		this(0, 0);
	}

	public Point(int x, int y)
	{
		setPosition(x, y);
	}

	public void setPosition(int x, int y)
	{
		this.x = x;
		this.y = y;
	}

	@Override
	public String toString()
	{
		return "(" + x + ", " + y + ")";
	}
}

Informuję, że w importach są zawarte literówki z powodu niemożności zapisu artykułu przez Joomlę (musi być usunięta litera "X"!).

Gdybyśmy czytali przepis "serializacja obiektów krok po kroku" brzmiałby mniej więcej tak:

  1. Utwórz obiekt, który ma być poddany serializacji danych.
  2. Zaimplementuj do niego interfejs "Serializable" w celu uprzedzenia kompilatora, że taki manewr ma być dopuszczony dla klasy.
  3. Dodaj specjalną właściwość do klasy o nazwie "serialVersionUID" typu "long" z modyfikatorami "private static final" jako stała statyczna (ARCYWAŻNY WPIS, szczegóły znajdują się w odrębnym artykule).
  4. Zdefiniuj funkcję serializującą obiekty dodając słowo kluczowe "throws", a w niej:
    1. zmienną typu "FileOutputStream" podając nazwę pliku do którego będą wrzucone dane
    2. zmienną typu "ObjectOutputStream" podając wcześniej utworzony obiekt
    3. wywołanie metody "writeObject" ze strumienia wyjściowego obiektów podając w nawiasy obiekt, który chcemy przechować
    4. wywołanie metody "close" zamykającej plik
  5. Zdefiniuj funkcję deserializującą (odczytującą) obiekty dodając słowo kluczowe "throws", a w niej:
    1. zmienną typu "FileInputStream" podając nazwę pliku z którego dane będą wyjmowane
    2. zmienną typu "ObjectInputStream" podając wcześniej utworzony obiekt
    3. przypisanie do każdego z obiektów wartości z wywoływanej metody "readObject" ZACHOWUJĄC TAKĄ SAMĄ KOLEJNOŚĆ i rzutując na odpowiednią klasę
    4. wywołanie metody "close" zamykającej plik
  6. Dodaj klauzulę "try-catch" przechwytującej wyjątki i zawrzyj odpowiednią metodę w zależności od tego, czy chcesz zapisać, czy odczytać z pliku. Serializacja obiektów korzysta z metod mogących zgłosić wyjątek. W przypadku zapisu, utwórz wpierw instancje obiektów, a potem wywołaj funkcję serializującą. W przypadku odczytu, nie twórz nowych kopii i wywołaj od razu funkcję deserializującą z przypisaniami do obiektów.
Serializacja obiektów w języku Java

Tak wyglądają "zmielone" dane składowe obiektów przechowujące wartości chronione przed edycją z zewnątrz.

Nie dostaliście oczopląsu? Mam taką nadzieję. Prościej się tego napisać już nie da, aby dało się to zaprogramować w obie strony. Serializacja obiektów ma ten duży plus, że zapobiega zewnętrznej edycji danych. Zostawiłem obrazek ukazujący jak wygląda plik z danymi przechowujący obiekty poddane serializacji.

Wpis "pl.jasonxiii.serialization" odnosi się do nazwy pakietu do którego wrzuciłem wszystkie klasy. Nie jest tu uwzględniony, aby nie czynić całego kodu jeszcze odrobinę większego (pakiety też doczekają się stosownego artykułu). Słowo kluczowe "throws" pozwala "przerzucić" odpowiedzialność przechwycenia wyjątku metodzie wywołującej, artykuł na ten temat został już opublikowany.


To wszystko na chwilę obecną, i tak zbyt poważnie to już wygląda.

PODOBNE ARTYKUŁY