What happens without serialization in Java?

Tonya 87 Published: 08/13/2024

What happens without serialization in Java?

I'll respond in English for this question.

Without serialization in Java, when an object is passed as an argument to a method, or stored in a data structure, its internal state (i.e., the values of its instance variables) is not preserved. This means that any changes made to the object's state will be lost once the reference to it goes out of scope.

Serialization in Java solves this problem by allowing you to convert an object into a byte stream, which can then be written to a file or transmitted over a network. When the serialized object is read back, its internal state is restored to the same value it had when it was originally serialized. This allows you to save and restore objects across different runs of your Java program, or even across different JVMs.

Here's what happens without serialization:

Let's say you have a class called Student with instance variables for the student's name, age, and GPA. You create a few instances of this class and store them in an array:

Student[] students = new Student[3];

students[0] = new Student("Alice", 20, 3.8);

students[1] = new Student("Bob", 21, 3.5);

students[2] = new Student("Charlie", 22, 3.9);

// ...

Now, suppose you want to send this array of students over a network to another Java program. Without serialization, you would have to create a new Student object on the receiving end and assign its instance variables manually:

Student[] receivedStudents = ...; // assuming it was sent over the network

for (int i = 0; i < receivedStudents.length; i++) {

Student student = new Student();

student.setName(receivedStudents[i].getName());

student.setAge(receivedStudents[i].getAge());

student.setGPA(receivedStudents[i].getGPA());

}

This is not only tedious, but also prone to errors and difficult to maintain. With serialization, you can simply serialize the Student[] array and send it over the network:

ObjectOutputStream os = ...; // assuming a network stream

os.writeObject(students);

On the receiving end, you can deserialize the object back into its original form:

ObjectInputStream is = ...; // assuming a network stream

Student[] receivedStudents = (Student[]) is.readObject();

Serialization makes your Java program more robust and easier to maintain by allowing you to store and retrieve complex objects.

how java serialization works internally

I'd be happy to explain how Java serialization works internally.

Java serialization is a mechanism that allows converting an object into a byte stream, which can then be written to a file or sent over a network connection. The process of serialization involves translating the object's state (its properties and fields) into a format that can be stored or transmitted. This format is called "serialized" data.

Here's how Java serialization works internally:

ObjectOutputStream: When you want to serialize an object, you create an instance of ObjectOutputStream class, which is responsible for serializing the object. Marking and writing fields: The ObjectOutputStream starts by marking the beginning of the serialized data with a special marker, called the "header". This header contains information about the version of serialization being used (Java 1.x, Java 5, etc.) and other metadata.

Then, for each non-static field in the object, the ObjectOutputStream writes:

The name of the field using a unique identifier The value of the field

This process is recursive; if a field contains an object, that object will be serialized as well. This ensures that all reachable objects from the original object are included in the serialization.

Writing class information: After writing all the fields, the ObjectOutputStream writes the fully qualified name (FQN) of the class of the serialized object. Optional extra data: Depending on the type of object being serialized and its fields, the ObjectOutputStream might write additional metadata, such as: Field names (for objects with dynamically generated field names) Class versions (to ensure compatibility between different Java versions) Footer and end marker: Finally, the ObjectOutputStream writes a footer that contains information about the number of bytes written and the type of serialization used.

When you write the serialized data to a file or send it over a network connection, it's represented as an array of bytes. The receiving party can then read this data using an instance of ObjectInputStream, which is responsible for deserializing the object.

Here's how Java deserialization works internally:

ObjectInputStream: When you want to deserialize an object from a byte stream, you create an instance of ObjectInputStream class. Reading fields and objects: The ObjectInputStream reads in the serialized data, starting with the header that contains metadata about the serialization version. Deserializing objects: For each field written during serialization, the ObjectInputStream re-creates the corresponding object. This includes recursively deserializing any contained objects. Populating fields and objects: After creating an object, the ObjectInputStream populates its fields with values read from the serialized data. Completed deserialization: Finally, the ObjectInputStream returns the fully deserialized object to your application.

That's a high-level overview of how Java serialization works internally!