# Serialization

## Overview

:white\_check\_mark: JDK1.1\
&#x20;Serialization is a process which **translates** a Java **object** into a sequence of **bytes**. [![Serialization](https://camo.githubusercontent.com/aa013a2a5854666d7f3912d7cb161817c2e2abb1/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f536f576b49496d6749536169494b7061716a5135306371354a413044612d4567474838414a5974414a437039683465696f537046307968516d4948684743677934696949574b6d436979315949504b62674931625f616250675361624539474c626e4962396b51324a4745317766485168436657444457427365497a75393251626d4273436d3030)](https://camo.githubusercontent.com/aa013a2a5854666d7f3912d7cb161817c2e2abb1/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f536f576b49496d6749536169494b7061716a5135306371354a413044612d4567474838414a5974414a437039683465696f537046307968516d4948684743677934696949574b6d436979315949504b62674931625f616250675361624539474c626e4962396b51324a4745317766485168436657444457427365497a75393251626d4273436d3030)

### Why do we need it?

* Normally the maximum life time of the object is from the program start till the program end. Serialization may help to *keep object alive* between the program executions.
* **Serialized** object (as a byte stream) can be saved to the file and **transferred** by the **network**.
* Serialization enables [Java RMI](https://docs.oracle.com/javase/8/docs/technotes/guides/rmi/faq.html) (Remote Method Invocation) to be performed.

### How to make a class Serializable

The class needs to implement a marker interface to become a Serializable.

```java
public class User implements Serializable {}
```

### Simple code example

The example demonstrates a serializable class, which is being serialized and deserialized through saving to the file inside of the test.

```java
public class User implements Serializable {
	private static final long serialVersionUID = 1L;
	
	/**
	 * Static field belongs to the class, not to the instance.
	 * So it is not serialized.
	 */
	static String address = "theEarthPlanet";
	private int age;
	private String name;
	
	/**
	 * Transient fields are ignored during serialization.
	 */
	transient int height;

    // getters and setters of the fields
	}
```

Below is a test which performs serialization and deserialization of the user instance. Pay attention that *transient* class field `height` is ignored during the process of serialization.

```java
public class SimpleSerialization {
	
	@Test
	public void whenSerializedAndDeserialized_objectIsTheSame() throws IOException, ClassNotFoundException {
	    // Arrange
		User user = new User();
		user.setAge(20);
		user.setName("theName");
		user.setHeight(180);
		
		String fileName = "theFile.txt";
		writeObjectToFile(user, fileName);
		
		// Act
		Object object = readObjectFromFile(fileName);
		User deserializedUser = (User) object;
		
		// Assert
		assertThat(deserializedUser.getAge()).isEqualTo(user.getAge());
		assertThat(deserializedUser.getName()).isEqualTo(user.getName());
		
		assertThat(deserializedUser.getHeight()).isNotEqualTo(user.getHeight());
	}
	
	
	private Object readObjectFromFile(String fileName) throws IOException, ClassNotFoundException {
		FileInputStream fileInputStream
				= new FileInputStream(fileName);
		ObjectInputStream objectInputStream
				= new ObjectInputStream(fileInputStream);
		Object object = objectInputStream.readObject();
		objectInputStream.close();
		return object;
	}
	
	
	private void writeObjectToFile(User user, String fileName) throws IOException {
		FileOutputStream fileOutputStream
				= new FileOutputStream(fileName);
		ObjectOutputStream objectOutputStream
				= new ObjectOutputStream(fileOutputStream);
		objectOutputStream.writeObject(user);
		objectOutputStream.flush();
		objectOutputStream.close();
	}
}
```

A source code can be found [here](https://github.com/amartyushov/Experiments/blob/master/java/features/serialization/src/test/java/io/mart/SimpleSerialization.java).

### Classes involved in serialization/deserialization

[![classes](https://camo.githubusercontent.com/6636640ed080683c8bd166d03ce18c039800596b/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f536f576b49496d6741537444754966384a4376454a347a4c6f346569497a4a4270355565766b42594a4376394232764d79345f414961716b79536d6841327139425962414a536d356f64356f51614635354f30594148326358594f4e506f7243357639774439467949716c475a49684270716e4841325f414234633563574772456e5f504842302d5839373833684166714b743942795f4a6e4e4768356f543236775032353244686b486e49797241304f473430)](https://camo.githubusercontent.com/6636640ed080683c8bd166d03ce18c039800596b/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f536f576b49496d6741537444754966384a4376454a347a4c6f346569497a4a4270355565766b42594a4376394232764d79345f414961716b79536d6841327139425962414a536d356f64356f51614635354f30594148326358594f4e506f7243357639774439467949716c475a49684270716e4841325f414234633563574772456e5f504842302d5839373833684166714b743942795f4a6e4e4768356f543236775032353244686b486e49797241304f473430)\
&#x20;Class `ObjectOutputStream` using a method

```java
public final void writeObject(Object o) throws IOException;
```

can write primitive types or graph of objects to an `OutputStream` as a stream of bytes.\
&#x20;And streams can then be read using `ObjectInputStream` by the method

```java
public final Object readObject() throws IOException, ClassNotFoundException;
```

:warning: TODO \
&#x20;Create a sequence diagram of serialization/deserialization.

### Caveats: Inheritance and Composition

[![Inheritance](https://camo.githubusercontent.com/641954a52a23b579630279528d8a19ab45d078b8/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f5a4f7a316869393032385274643838426a305475554f6b6b7a30307a304e52476159324a304151397956334d45386c48624a6c2d5f7546614f756561707a6a4c3048516232336d774d4a6247686b6f6a554753346779646553626470336f4b6d73384c4b78644849485768534d424c5470444c2d735850427a5a436a5a374537305667345f757a6e5f42336776587145664d7573443464756862796334726c5037746d32)](https://camo.githubusercontent.com/641954a52a23b579630279528d8a19ab45d078b8/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f5a4f7a316869393032385274643838426a305475554f6b6b7a30307a304e52476159324a304151397956334d45386c48624a6c2d5f7546614f756561707a6a4c3048516232336d774d4a6247686b6f6a554753346779646553626470336f4b6d73384c4b78644849485768534d424c5470444c2d735850427a5a436a5a374537305667345f757a6e5f42336776587145664d7573443464756862796334726c5037746d32)\
&#x20;When a class implements an interface `java.io.Serializable` all its subclasses are becoming serializable as well.\
&#x20;There is an example of inheritance for serialization. [example](https://github.com/amartyushov/Experiments/blob/master/java/features/serialization/src/test/java/io/mart/SerializationInheritance.java)

[![Composition](https://camo.githubusercontent.com/75fb5a4469c65043a30db5a30197d4506f1dbcfa/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f504b7a423269435734447278326a53355375386b30653749544e4532595063716d6148583732634b37687548585966617a2d507a746a436e3278324b644f706e313364524871656f4c514a7446504d4359595457484e44505636557739534f69396148317469325a645034334b465a3047635843567a6468546e5a516f62644a6e4a4456725f2d76577439685561564e646a4171592d466d5638644a676275577430772d4c63636b532d696c48656e6873556137)](https://camo.githubusercontent.com/75fb5a4469c65043a30db5a30197d4506f1dbcfa/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f504b7a423269435734447278326a53355375386b30653749544e4532595063716d6148583732634b37687548585966617a2d507a746a436e3278324b644f706e313364524871656f4c514a7446504d4359595457484e44505636557739534f69396148317469325a645034334b465a3047635843567a6468546e5a516f62644a6e4a4456725f2d76577439685561564e646a4171592d466d5638644a676275577430772d4c63636b532d696c48656e6873556137)\
&#x20;In case a class is composed of other classes, then each of these classes has to implement `java.io.Serializable` otherwise an exception `NotSerializableException` will be thrown during serialization process.\
&#x20;On the diagram a class `RootClass` can be serialized.\
&#x20;But during serialization of class `Subclass` an exception `NotSerializableException` is thrown, because one of the `Subclass` fields is a nonSerializable class (and it is **important** that value for this field is set, otherwise a field value is `null` and no exception is thrown during serialization).\
&#x20;There is an example of composition for serialization. [example](https://github.com/amartyushov/Experiments/blob/master/java/features/serialization/src/test/java/io/mart/SerializationComposition.java)

[![Inheritance correct case](https://camo.githubusercontent.com/254f9dd809b76817953617e3bb48b3b39fad4c3d/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f4a5376313269393033304e47544e454142314d503761315335426f3071314634446365577049414a6b623178546d546347395676554e702d6138437972614b3139674d53794b4245356c57367831382d494c532d7558576b5465566b71427778464d6f44646e2d59537a3435366f715f6b75354f69447a654f587050584c485554354b362d425f6d7a456478735736726b5947666a4d485763796b6f426d3030)](https://camo.githubusercontent.com/254f9dd809b76817953617e3bb48b3b39fad4c3d/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f4a5376313269393033304e47544e454142314d503761315335426f3071314634446365577049414a6b623178546d546347395676554e702d6138437972614b3139674d53794b4245356c57367831382d494c532d7558576b5465566b71427778464d6f44646e2d59537a3435366f715f6b75354f69447a654f587050584c485554354b362d425f6d7a456478735736726b5947666a4d485763796b6f426d3030)\
&#x20;There is an edge case when subclass implements `Serializable`, but parent class not. [Link](https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html) to javadoc.\
&#x20;Only the **fields of Serializable objects** are written out and restored.\
&#x20;In current case it means that for `Child` objects, assuming both `value` and `name` were set to the object only `name` field values will be serialized/deserialized. And there will be no Runtime exceptions in this case.\
&#x20;And fields of non-serializable `Parent` class will be initialised using its no-args constructor (public or protected), so this constructor should be accessible to the `Child` class. There is an example, which demonstrates the edge case for inheritance. [example](https://github.com/amartyushov/Experiments/blob/master/java/features/serialization/src/test/java/io/mart/SerializationInheritanceForSubclassCorrectCase.java)

[![Inheritance incorrect case](https://camo.githubusercontent.com/f5d080262dc17519b5cff6806cc992593e806432/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f4a4f7a446f6544303334334e7658485056587a62463831714f55613532637778594d457130734336436836425f6a6f7a476e4e67436b2d48487a396338784c625a57302d4b697675384d4b6e5630394d336b794b3573776d436d716f474e4e4f78442d4e5f7943523931625a7644345146464d7641394a614941547935507961636f785561637866796f7434655048424d365a55547256726f6d4f6e726634794f79535141384f377a5034317a5843554e744d7a426939774c593745525148623653664e376d3030)](https://camo.githubusercontent.com/f5d080262dc17519b5cff6806cc992593e806432/687474703a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f706e672f4a4f7a446f6544303334334e7658485056587a62463831714f55613532637778594d457130734336436836425f6a6f7a476e4e67436b2d48487a396338784c625a57302d4b697675384d4b6e5630394d336b794b3573776d436d716f474e4e4f78442d4e5f7943523931625a7644345146464d7641394a614941547935507961636f785561637866796f7434655048424d365a55547256726f6d4f6e726634794f79535141384f377a5034317a5843554e744d7a426939774c593745525148623653664e376d3030)\
&#x20;There is an edge case for inheritance which will throw an exception in runtime.\
&#x20;So the subclass `Child` is implementing `Serializable`, but its super class not.\
&#x20;**Plus** there is not default constructor for super class `Parent`, it means that during **deserialization** there is no possibility to initialise fields from super class and exception **java.io.InvalidClassException** will be thrown in runtime (`serialization` happens without exceptions). There is an example, which demonstrates this edge case of throwing exception [example](https://github.com/amartyushov/Experiments/blob/master/java/features/serialization/src/test/java/io/mart/SerializationInheritanceForSubclassIncorrectCase.java)

### Serial version UID

It is *strongly recommended* that all serializable classes explicitly declare the **private** field ( this field is not useful for inheritance):

```java
private static final long serialVersionUID = 42L;
```

#### Why do we need this field?

* the serialization runtime **associates** each serializable **class** with a **version** number, so this field is a version number
  * if this field is **not** deliberately **specified** in serializable class
    * \=> serialization runtime **calculate** default serialVersionUID for this class based on its **attributes**, associated access **modifiers**
    * \=> when you add/modify any field in class, which is already serialized, => class will not be able to recover, because serialVersionUID generated for new class and for old serialized are different => exception java.io.InvalidClassException is thrown
* &#x20;this field is used during **deserialization** to verify that saved and loaded objects have the same attributes and thus are compatible on serialization

There is an example where fragility of `serialVersionUID` is demonstrated. [example](https://github.com/amartyushov/Experiments/blob/master/java/features/serialization/src/test/java/io/mart/SerialVersionUIDTest.java)

### Custom serialization

:warning: TODO
