Menu

Dla programistów

Szymon Trawiński

Jak zacząć?

Co to jest serializer?

Jest to zbiór klas, który pozwala na tzw. „serializację” obiektu. Po ludzku znaczy to tyle, że każdą napisaną przez kogoś klasę, która implementuje interfejs serializable możemy zamienić w strumień bitowy i przechować w pliku, bądź bazie danych. Późniejsza „deserializacja” pozwala na wierne odtworzenie klasy. Serializacja jest niezależna od systemu operacyjnego.

Co więcej serializowane obiekty są zamrażane w trakcie działania programu, tak więc mamy możliwość zapisania stanu serializowanego obiektu (wartości zmiennych czy stanu obiektów), po czym go odtworzyć i wykonywać dalej, np. na innym komputerze. Wniosek: długość 'życia' programu nie ogranicza długości życia obiektu. Ta właściwość jest nazywana 'lekką trwałością' (ang. lightweight persistence).

Więcej w: B. Eckel, „Thinking in Java”, s. 803 – 821.

Cały proces realizacji projektu zacząłbym, kolejno, od:

  1. Na początku warto poznać mechanizmy RTTI w Javie (ang. Run-time type information), czyli dosłownie identyfikowaniu typu obiektu w trakcie działania programu i przyjrzeć się obiektowi Class, na którym będziemy w znacznej części operować. Wbudowane metody obiektu Class pozwalają na pozyskanie pól, obiektów i metod zawartych w danej klasie. W ten sposób będziemy mogli rozebrać obiekt na części pierwsze i przewidzieć sposób serializacji.
  2. Kiedy już będzie mniej więcej wiadome jaka jest idea serializera proponuję przejrzeć przykładowe open-source'owe serializery, np. http://java2s.com/Open-Source/Java/Game/jgf/com/jme3/network/serializing/Serializer.java.htm, http://xstream.codehaus.org/download.html
  3. Przyjrzeć się temu:

Eeee... dobra. Sourceforge do bani formatuje, ale kod jest gotowy do przeklejenia do Eclipse'a.

//********
// To jest jedynie przyklad uzywania 'Class', refleksji obiektu itd.
// Uprzedzam, ze kod moze byc zle napisany i na pewno nie tak bedzie wygladal
// nasz serializer. W kazdym razie jakby ktos mial problemy z 'Class'
// to niech sie temu przyjrzy, moze cos pomoze, rozjasni...
//
********

package serializer;

import java.lang.reflect.Field;
import java.util.ArrayList;

class MojaKlasa {
//***
// przykladowa klasa do serializowania
//
***
private int a = 5;
final double b = 10.5;
static Integer c = new Integer(15);
Double d = new Double(20.5);
String string = new String("uaua");

ArrayList<Integer> alInteger = new ArrayList<Integer>();

public void wypiszWartosci() {
    System.out.println("a = " + this.a);
    System.out.println("b = " + this.b);
    System.out.println("c = " + c);
    System.out.println("d = " + this.d);
    System.out.println("string = " + this.string);
    System.out.println("alInteger = " + this.alInteger);
}

}

public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {

    Main majna = new Main();
    MojaKlasa mojaKlasa = new MojaKlasa();

    majna.Serialize(mojaKlasa);
}

public void Serialize(Object obj) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException {
    //*********************
    // PROBA SERIALIZACJI
    //*********************
    System.out.println("SERIALIZE...");
    Class cls= Class.forName(obj.getClass().getName()); // tworzenie 'Class' z dowolnego obiektu

    Field[] pole = cls.getDeclaredFields(); // nazwy pol
    Object[] values = new Object[pole.length]; // wartosci pol

    for(int i = 0; i < pole.length; i++) {
        pole[i].setAccessible(true); // ta linijka pozwala na dostep do prywatnych zmiennych
        values[i] = pole[i].get(obj); // pobieramy wartosci kazdego pola kolejno
        System.out.println(pole[i].getName() + " = " + values[i]);
    }

    // WNIOSEK: potrafimy spisac nazwy argumentow i ich wartosci. Majac te dane mozemy probowac serializowac obiekt.

    //**********************
    // PROBA DESERIALiZACJI
    //**********************
    // to taka jakby deserializacja z tym, ze testowa dlatego wszystko jest w jednej metodzie

    Object objCopy = cls.newInstance(); // tworzymy kopie obiektu 'obj' za pomoca 'Class' - robimy to dlatego, ze nie mamy samodzielnego obiektu

    for(int i = 0; i < pole.length; i++) {
        pole[i].set(objCopy, values[i]); // ustawiamy kazda wartosc kolejno
    }

    // no i obiekt jest gotowy - w takiej postaci prawdopodobnie zwrocimy do uzytkownikowi. On sam (chyba) bedzie musial dokonac rzutowania na swoj typ
    // sprawdzmy, czy wszystko jest ok
    System.out.println("DESERIALIZE...");
    MojaKlasa userObject = (MojaKlasa) objCopy;
    userObject.wypiszWartosci();

}}

MongoDB Logo MongoDB