# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://amartyushov.gitbook.io/tech/programming-languages/java/serialization.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
