Serializacja to mechanizm konwersji stanu obiektu na strumień bajtów. Deserializacja to proces odwrotny, w którym strumień bajtów jest używany do odtworzenia rzeczywistego obiektu Java w pamięci. Mechanizm ten służy do utrwalania obiektu.
Utworzony strumień bajtów jest niezależny od platformy. Zatem obiekt serializowany na jednej platformie można deserializować na innej platformie. Aby umożliwić serializację obiektu Java, implementujemy metodę Możliwość serializacji java.io interfejs. Klasa ObjectOutputStream zawiera napiszObiekt() metoda serializacji obiektu.
public final void writeObject(Object obj) throws IOException>
Klasa ObjectInputStream zawiera przeczytajObiekt() metoda deserializacji obiektu.
public final Object readObject() throws IOException, ClassNotFoundException>
Zalety serializacji
- Aby zapisać/utrwalić stan obiektu.
- Aby podróżować obiektem przez sieć.
Serializować można tylko obiekty tych klas, które są implementowane Możliwość serializacji java.io interfejs. Możliwość serializacji to a interfejs znacznika (nie ma elementu danych i metody). Służy do oznaczania klas Java, aby obiekty tych klas mogły uzyskać określone możliwości. Inne przykłady interfejsów znaczników to: - Klonowane i zdalne.
Punkty do zapamiętania
1. Jeśli klasa nadrzędna ma zaimplementowany interfejs Serializable, to klasa potomna nie musi go implementować, ale odwrotnie nie jest to prawdą.
2. W procesie serializacji zapisywane są tylko niestatyczne elementy danych.
3. Elementy danych statycznych i przejściowych nie są zapisywane w procesie serializacji. Jeśli więc nie chcesz zapisywać wartości niestatycznego elementu danych, ustaw go jako przejściowy.
4. Konstruktor obiektu nigdy nie jest wywoływany podczas deserializacji obiektu.
5. Powiązane obiekty muszą implementować interfejs Serializable. Przykład :
class A implements Serializable{ // B also implements Serializable // interface. B ob=new B(); }>
Wersja seryjnaUID Środowisko wykonawcze Serialization kojarzy numer wersji z każdą klasą Serializable o nazwie SerialVersionUID, która jest używana podczas deserializacji w celu sprawdzenia, czy nadawca i odbiorca serializowanego obiektu załadowali klasy dla tego obiektu, które są zgodne pod względem serializacji. Jeśli odbiorca załadował klasę dla obiektu, który ma inny UID niż klasa odpowiedniego nadawcy, deserializacja zakończy się Nieprawidłowy wyjątek klasy .
Klasa Serializable może jawnie zadeklarować swój własny UID, deklarując nazwę pola. Musi być statyczny, końcowy i mieć długi typ. tj. ANY-ACCESS-MODIFIER statyczny końcowy długi serialVersionUID=42L; Jeśli klasa możliwa do serializacji nie zadeklaruje jawnie identyfikatora serialVersionUID, środowisko wykonawcze serializacji obliczy wartość domyślną dla tej klasy na podstawie różnych aspektów klasy, zgodnie z opisem w Specyfikacji serializacji obiektów Java. Jednak zdecydowanie zaleca się, aby wszystkie klasy możliwe do serializacji jawnie deklarowały wartość serialVersionUID, ponieważ jej obliczenia są bardzo wrażliwe na szczegóły klasy, które mogą się różnić w zależności od implementacji kompilatora, każda zmiana klasy lub użycie innego identyfikatora może mieć wpływ na serializowane dane. Zalecane jest również użycie prywatnego modyfikatora dla UID, ponieważ nie jest on przydatny jako dziedziczony element członkowski. serialer Serialver to narzędzie dostarczane z JDK. Służy do uzyskania numeru serialVersionUID dla klas Java.
Możesz uruchomić następującą komendę, aby uzyskać serialVersionUID [-classpath ścieżka klasy] [-show] [nazwa klasy…] Przykład 1:
Jawa
// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Demo> implements> java.io.Serializable> {> > public> int> a;> > public> String b;> > // Default constructor> > public> Demo(> int> a, String b)> > {> > this> .a = a;> > this> .b = b;> > }> }> class> Test> {> > public> static> void> main(String[] args)> > {> > Demo object => new> Demo(> 1> , 'geeksforgeeks');> > String filename = 'file.ser';> > > // Serialization> > try> > {> > //Saving of object in a file> > FileOutputStream file => new> FileOutputStream(filename);> > ObjectOutputStream out => new> ObjectOutputStream(file);> > > // Method for serialization of object> > out.writeObject(object);> > > out.close();> > file.close();> > > System.out.println('Object has been serialized');> > }> > > catch> (IOException ex)> > {> > System.out.println('IOException is caught');> > }> > Demo object1 => null> ;> > // Deserialization> > try> > {> > // Reading the object from a file> > FileInputStream file => new> FileInputStream(filename);> > ObjectInputStream in => new> ObjectInputStream(file);> > > // Method for deserialization of object> > object1 = (Demo)in.readObject();> > > in.close();> > file.close();> > > System.out.println('Object has been deserialized ');> > System.out.println('a = ' + object1.a);> > System.out.println('b = ' + object1.b);> > }> > > catch> (IOException ex)> > {> > System.out.println('IOException is caught');> > }> > > catch> (ClassNotFoundException ex)> > {> > System.out.println('ClassNotFoundException is caught');> > }> > }> }> |
>
>
Wyjście :
Object has been serialized Object has been deserialized a = 1 b = geeksforgeeks>
Przykład 2:
Jawa
// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Emp> implements> Serializable {> private> static> final> long> serialversionUID => > 129348938L;> > transient> int> a;> > static> int> b;> > String name;> > int> age;> > // Default constructor> public> Emp(String name,> int> age,> int> a,> int> b)> > {> > this> .name = name;> > this> .age = age;> > this> .a = a;> > this> .b = b;> > }> }> public> class> SerialExample {> public> static> void> printdata(Emp object1)> > {> > System.out.println('name = ' + object1.name);> > System.out.println('age = ' + object1.age);> > System.out.println('a = ' + object1.a);> > System.out.println('b = ' + object1.b);> > }> public> static> void> main(String[] args)> > {> > Emp object => new> Emp('ab',> 20> ,> 2> ,> 1000> );> > String filename = 'shubham.txt';> > // Serialization> > try> {> > // Saving of object in a file> > FileOutputStream file => new> FileOutputStream> > (filename);> > ObjectOutputStream out => new> ObjectOutputStream> > (file);> > // Method for serialization of object> > out.writeObject(object);> > out.close();> > file.close();> > System.out.println('Object has been serialized
'> > + 'Data before Deserialization.');> > printdata(object);> > // value of static variable changed> > object.b => 2000> ;> > }> > catch> (IOException ex) {> > System.out.println('IOException is caught');> > }> > object => null> ;> > // Deserialization> > try> {> > // Reading the object from a file> > FileInputStream file => new> FileInputStream> > (filename);> > ObjectInputStream in => new> ObjectInputStream> > (file);> > // Method for deserialization of object> > object = (Emp)in.readObject();> > in.close();> > file.close();> > System.out.println('Object has been deserialized
'> > + 'Data after Deserialization.');> > printdata(object);> > // System.out.println('z = ' + object1.z);> > }> > catch> (IOException ex) {> > System.out.println('IOException is caught');> > }> > catch> (ClassNotFoundException ex) {> > System.out.println('ClassNotFoundException' +> > ' is caught');> > }> > }> }> |
>
>
Wyjście:
Object has been serialized Data before Deserialization. name = ab age = 20 a = 2 b = 1000 Object has been deserialized Data after Deserialization. name = ab age = 20 a = 0 b = 2000>
Opis wyjścia: Podczas deserializacji obiektu zauważyłeś, że zmieniły się wartości a i b. Przyczyną bycia a została oznaczona jako przejściowa, a b była statyczna.
W przypadku zmienne przejściowe: - Zmienna zdefiniowana za pomocą słowa kluczowego transient nie jest serializowana podczas procesu serializacji. Ta zmienna zostanie zainicjowana wartością domyślną podczas deserializacji. (np. dla obiektów jest to null, dla int jest to 0).
W przypadku Zmienne statyczne:- Zmienna zdefiniowana za pomocą słowa kluczowego static nie jest serializowana podczas procesu serializacji. Zmienna ta zostanie załadowana bieżącą wartością zdefiniowaną w klasie podczas deserializacji.
Przejściowe kontra końcowe:
finał zmienne będą uczestniczyć w serializacji bezpośrednio poprzez ich wartości.
Dlatego deklarowanie zmiennej końcowej jako przejściowej nie ma sensu.
//kompilator przypisuje wartość zmiennej końcowej
przykład:
final int x= 10; int y = 20; System.out.println(x);// compiler will replace this as System.out.println(10)->10, ponieważ x jest ostateczne. System.out.println(y);//20>
Przykład 3:
Jawa
wielkaandra
//java code for final with transient> import> java.io.*;> class> Dog> implements> Serializable{> > int> i=> 10> ;> > transient> final> int> j=> 20> ;> }> class> GFG {> > public> static> void> main (String[] args)> throws> IOException,ClassNotFoundException> > {> > Dog d1=> new> Dog();> > //Serialization started> > System.out.println(> 'serialization started'> );> > FileOutputStream fos=> new> FileOutputStream(> 'abc.ser'> );> > ObjectOutputStream oos=> new> ObjectOutputStream(fos);> > oos.writeObject(d1);> > System.out.println(> 'Serialization ended'> );> > > //Deserialization started> > System.out.println(> 'Deserialization started'> );> > FileInputStream fis=> new> FileInputStream(> 'abc.ser'> );> > ObjectInputStream ois=> new> ObjectInputStream(fis);> > Dog d2=(Dog) ois.readObject();> > System.out.println(> 'Deserialization ended'> );> > System.out.println(> 'Dog object data'> );> > //final result> > System.out.println(d2.i+> ' '> +d2.j);> > }> }> |
>
>Wyjście
serialization started Serialization ended Deserialization started Deserialization ended Dog object data 10 20>