Wznawiam temat serializacji danych w języku Java. Wyobraźmy sobie taką sytuację. Mamy naszą klasę, implementujemy interfejs "Serializable" i każemy programowi zapisać wszystkie dane składowe...oprócz jednej! Takiej małej zmiennej, która powinna być pomijana ze względu na wartość unikalną dla konkretnego uruchomienia aplikacji. O Boże! Czy to znaczy, że z powodu takiej błahostki, serializacja obiektów idzie w drzazgi i trzeba od razu przerzucać cały system przechowywania do pliku tekstowego? Niekoniecznie! Twórcy języka i o takiej sytuacji pomyśleli więc mogę ją teraz zaprezentować. Poznajcie kolejne słowo kluczowe związane z wykluczaniem danych składowych do zapisu, "transient"!

SERIALIZACJA OBIEKTÓW Z WYKLUCZENIEM

Modyfikator "transient" zapobiega uwzględnianiu pewnej danej składowej przy serializacji danych gdy mamy pewność, że ona pod żadnym pozorem nie powinna być brana pod uwagę. Mogą być takie sytuacje, które wymagają pewnych wykluczeń. Na przykład operacja uzyskania dostępu do konta bankowego. Przecież nie ma najmniejszego sensu serializowania podanego hasła do konta, bo wtedy całe zabezpieczenie na nic! Serializacja obiektów kont bankowych musi wówczas wstawić "transient" przy polu hasła (prawdopodobnie "String"), aby wymusić na użytkowniku ponowne wprowadzanie hasła do systemu.

Powyższe słówko przydaje się również w sytuacjach, gdy pewne dane składowe są obliczane podczas wykonywania programu i te wartości muszą być unikatowe przy każdym uruchomieniu! Dla przykładu jakieś nawiązywanie połączeń sieciowych. Choć można uznać za logiczne przechowywanie loginów naszych znajomych, to jednak samo połączenie nie może zostać zapisane, ponieważ proces ich inicjowania i utrzymywania jest zależna od wielu czynników, na przykład od systemu operacyjnego.

Serializacja obiektów - wykluczanie przy pomocy "transient"

Modyfikator "transient" odpowiada za "wykluczanie" danych składowych podczas serializacji danych.

KOD ŹRÓDŁOWY RAZ JESZCZE!

Serializacja obiektów po raz kolejny doczeka się świateł reflektorów. Kierujemy się na poniższy program i staramy się go samodzielnie przeanalizować:

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

public class Account implements Serializable
{
	private String login;
	private transient String password;

	public Account(String login, String password)
	{
		this.login = login;
		this.password = password;

		System.out.println("Konto zostało utworzone.");
	}

	@Override
	public String toString()
	{
		return "Login: " + login + ", Hasło: " + password;
	}
}
  • KLASA "Serialization"
import java. io.*;

public class Serialization
{
	private static final String SAVE_FILENAME = "accounts.dat";

	private Account accountA, accountB;

	public Serialization()
	{
		createInstances();

		try
		{
			serialize();
			//deserialize();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		printAccounts();
	}

	private void createInstances()
	{
		accountA = new Account("gierka876", "zagrajZeMna01");
		accountB = new Account("sfinks56", "prosteZasady_4");
	}

	private void serialize() throws IOException
	{
		FileOutputStream fos = new FileOutputStream(SAVE_FILENAME);
		ObjectOutputStream oos = new ObjectOutputStream(fos);

		oos.writeObject(accountA);
		oos.writeObject(accountB);
		oos.close();
	}

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

		accountA = (Account)ois.readObject();
		accountB = (Account)ois.readObject();

		ois.close();
	}

	private void printAccounts()
	{
		System.out.println(accountA);
		System.out.println(accountB);
	}
}

Aby zobaczyć cały efekt od początku do końca, trzeba odpowiednio przełączyć metody. Jeśli serializacja obiektów, to "createInstances" i "serialize" mają być odkomentowane. Gdy w drugą stronę, zakomentować obie powyższe metody i wywołać "deserialize". Gdy tak uczynimy, ujrzymy wczytywanie obu kont bankowych, ale bez hasła (wartość będzie "null"), dzięki użyciu modyfikatora "transient".

Jeśli nie wierzycie, OK! Usuńcie sobie to słowo i dokonajcie ponownego zapisu i odczytu a sami zobaczycie, że wówczas hasło zostanie zachowane. Pomijając fakt, iż taki system nie nadawałby się do niczego, to powyższy przykład dobitnie pokazuje jak działa "omijanie" danej składowej.


Oto koniec przemówienia. Serializacja obiektów musi być przeprowadzana zdroworozsądkowo, aby pewne dane naprawdę odstąpić od przechowania nie tylko ze względów bezpieczeństwa, ale też możliwości prawidłowego działania aplikacji. Nie ma problemu jeśli po serializacji usuwamy ten modyfikator, aczkolwiek jeśli "transient" został teraz dodany, a w czasie zapisu był "zwykłą" daną składową, możemy mieć duże problemy, które są związane z opisanym już zagadnieniem, "serialVersionUID".

PODOBNE ARTYKUŁY