🛑 1. Prevent Serialization of a Whole Class
Option A: Don’t implement Serializable
🚫 If a class doesn’t implement
Serializable
, it can’t be serialized.
public class NotSerializable {
int x = 10;
}
Trying to serialize it:
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file.ser"));
out.writeObject(new NotSerializable()); // ❌ Throws NotSerializableException
✅ Simple and effective.
Option B: Implement Serializable
but fail on purpose
If you have to implement Serializable
(e.g. subclassing), but want to block serialization, override writeObject()
and throw an exception:
private void writeObject(ObjectOutputStream out) throws IOException {
throw new NotSerializableException("Serialization is forbidden!");
}
✅ Good for stopping accidental usage.
🚫 2. Prevent Serialization of Specific Fields
Use the transient
keyword:
class User implements Serializable {
String username;
transient String password; // ❌ Not serialized
}
✅ The password
will be skipped and restored as null
.
🔐 3. Block Deserialization
You can override readObject()
to prevent loading the object:
private void readObject(ObjectInputStream in) throws IOException {
throw new InvalidObjectException("Deserialization not allowed.");
}
✅ Use this if you want to prevent old data or untrusted streams from loading sensitive objects.
⚙️ 4. Mark the Class as Abstract or an Interface
If a class is abstract
, it can’t be instantiated or serialized directly:
public abstract class AbstractThing implements Serializable { }
✅ Only subclasses (that are serializable) can be used.
🧵 TL;DR
Goal | Technique | Code/Keyword |
---|---|---|
Prevent entire class | Don’t implement Serializable | – |
Fail deliberately | Throw exception in writeObject() / readObject() | throw new NotSerializableException() |
Skip certain fields | Use transient | transient String token; |
Prevent deserialization | Override readObject() to fail | throw new InvalidObjectException() |
Block base usage | Use abstract | abstract class ... |