🧬
Memory & Lifecycle

Init Blocks, Cloning & Serialization

Object Lifecycle Extras
💡 A static block is a building's "one-time" inauguration — it runs exactly once, when the class loads. Cloning is a photocopier that makes an exact copy of an object. Serialization is packing an object into a suitcase to send somewhere, so you can later unpack (deserialize) the exact same thing.

A static block { } runs once, the moment the class loads — best for initializing static variables. An instance block runs every time an object is created (before the constructor).

clone() is a method from the Object class that creates a copy of an existing object (you need to implement the Cloneable interface).

Implementing the Serializable interface lets you convert an object into bytes (e.g. to save to a file or send over a network), and later deserialize it back into an object.

class Config implements Cloneable, Serializable {
  static { System.out.println("Loaded once!"); }
  int value = 10;
}
🧬
A static block is a building's "one-time" inauguration — it runs exactly once, when the class loads. Cloning is a photocopier that makes an exact copy of an object. Serialization is packing an object into a suitcase to send somewhere, so you can later unpack (deserialize) the exact same thing.
1 / 5
⚡ Quick Recap
  • static block = runs once when the class loads
  • clone() = a copy of the object
  • Serializable = save/send an object, rebuild it later
On this page (4 subtopics)

Shallow clone (the default clone() behavior, inherited from the Object class) only copies top-level fields — if a field is itself an object (a reference type), both clones point to the *same* nested object (changing it in one shows up in the other too, since the reference was copied, not the object).

Deep clone copies nested objects individually too — a completely independent copy, but you have to implement it manually (calling clone() on every nested object too, recursively).

Shallow CloneDeep Clone
Primitive fieldsGet copiedGet copied
Reference fields (objects)Same object sharedA new independent copy is made
Implementing itEasy (default clone())Manual, clone every nested object
// Shallow: dono objects ka "address" field same object point karta hai
Person clone = original.clone();
clone.address.city = "Mumbai"; // original.address.city bhi change ho jaayega!

When you need to skip certain fields during serialization (like a password, or a re-computable cache, or a field that isn't even Serializable, like a Thread), mark them transient — these fields get ignored while serializing, and get their default value (0/null) on deserialization.

class User implements Serializable {
  String username;
  transient String password; // serialize NAHI hoga
}
⚠️Common Mistake: If a class has a field that isn't itself Serializable (like a Thread or Socket object), and you don't mark it transient, trying to serialize the whole class will throw a NotSerializableException.

Defining a static final long serialVersionUID in a Serializable class is best practice — it's a "version number" that tells you what the class's structure looked like when the object was serialized. If you don't write it explicitly, the JVM computes one automatically (from the class structure), but that can change depending on compiler/platform.

If the class changes later (a new field gets added) and you try to deserialize old serialized data, the JVM checks the serialVersionUID and detects an incompatible version (InvalidClassException) — keeping an explicit UID lets you control when something counts as "compatible".

When a class loads for the first time: (1) static variables/blocks run once in their declaration order (only once for the entire program). Every time an object gets created with "new": (2) instance variables/blocks run in declaration order, (3) then the constructor runs.

So a static block runs first (once, at class load), an instance block runs for every object, just before the constructor. With inheritance the order gets even more interesting — parent's static blocks first, then child's static blocks, then (when the object is being created) parent's instance blocks + constructor, then child's.