Init Blocks, Cloning और Serialization
Static block { } class load होते ही एक बार चलता है — static variables initialize करने के लिए best। Instance block हर object बनते वक़्त चलता है (constructor से पहले)।
clone() Object class का method है जो एक existing object की copy बना देता है (Cloneable interface implement करना पड़ता है)।
Serializable interface implement करके object को bytes में convert कर सकते हो (जैसे file में save करना या network पर भेजना), और बाद में deserialize करके वापस object बना सकते हो।
class Config implements Cloneable, Serializable {
static { System.out.println("Loaded once!"); }
int value = 10;
}Shallow clone (default clone() behavior, Object class se inherited) sirf top-level fields copy karta hai — agar field khud ek object (reference type) hai, dono clones us *same* nested object ko point karte hain (ek change karega to dusre mein bhi dikhega, kyunki reference copy hui hai, object nahi).
Deep clone nested objects ko bhi individually copy karta hai — poori tarah independent copy, lekin manually implement karna padta hai (har nested object ka bhi apna clone() call karna, recursively).
| Shallow Clone | Deep Clone | |
|---|---|---|
| Primitive fields | Copy hoti hain | Copy hoti hain |
| Reference fields (objects) | Same object share hota hai | Naya independent copy banta hai |
| Implement karna | Aasan (default clone()) | Manual, har nested object clone karna |
// 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!Serialization ke waqt kuch fields skip karna ho (jaise password, ya kisi cache jo re-computable hai, ya koi field jo Serializable hi nahi hai jaise Thread), unhe transient mark karo — serialize hote waqt ye fields ignore ho jaate hain, aur deserialize hone par unki default value (0/null) milti hai.
class User implements Serializable {
String username;
transient String password; // serialize NAHI hoga
}Serializable class mein ek static final long serialVersionUID define karna best practice hai — ye ek "version number" hai jo batata hai class ka structure kaisa tha jab object serialize hua. Agar tum ise explicitly nahi likhte, JVM automatically compute kar deta hai (class ke structure se), lekin ye compiler/platform ke hisaab se badal sakta hai.
Agar baad mein class change ho jaaye (naya field add ho) aur purana serialized data deserialize karo, JVM serialVersionUID check karke incompatible version detect kar leta hai (InvalidClassException) — explicit UID rakhne se tum control karte ho ki kab "compatible" maana jaaye.
Jab class pehli baar load hoti hai: (1) static variables/blocks unke declaration order mein ek baar chalte hain (poore program mein sirf ek baar). Har baar jab "new" se object banta hai: (2) instance variables/blocks declaration order mein chalte hain, (3) fir constructor chalta hai.
Isliye static block sabse pehle (ek baar, class load par), instance block har object ke liye constructor se just pehle. Inheritance ke saath order aur interesting ho jaata hai — parent ke static blocks pehle, phir child ke static blocks, phir (object banते waqt) parent ke instance blocks + constructor, phir child ke.