211
public class Contact implements Serializable {
    private String name;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
  1. When should I implement Serializable interface?
  2. Why do we do that?
  3. Does it give any advantages or security?
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
theJava
  • 14,620
  • 45
  • 131
  • 172
  • 5
    FYI the accepted answer here is incomplete and misleading, because it doesn't address the security drawbacks. See *Effective Java*, **item 86: Implement Serializable with great caution.** [Raedwald's answer here](https://stackoverflow.com/a/53889695/217324) saying not to use serialization is the correct one. – Nathan Hughes Jan 10 '19 at 15:05

3 Answers3

186
  1. From What's this "serialization" thing all about?:

    It lets you take an object or group of objects, put them on a disk or send them through a wire or wireless transport mechanism, then later, perhaps on another computer, reverse the process: resurrect the original object(s). The basic mechanisms are to flatten object(s) into a one-dimensional stream of bits, and to turn that stream of bits back into the original object(s).

    Like the Transporter on Star Trek, it's all about taking something complicated and turning it into a flat sequence of 1s and 0s, then taking that sequence of 1s and 0s (possibly at another place, possibly at another time) and reconstructing the original complicated "something."

    So, implement the Serializable interface when you need to store a copy of the object, send them to another process which runs on the same system or over the network.

  2. Because you want to store or send an object.

  3. It makes storing and sending objects easy. It has nothing to do with security.

Kasun Siyambalapitiya
  • 3,956
  • 8
  • 38
  • 58
moinudin
  • 134,091
  • 45
  • 190
  • 216
  • 7
    Is it a best practice to implement seriablizble interface to all of domain models... – theJava Dec 28 '10 at 19:39
  • 13
    @theJava It's not a question of best practices. It's a question of whether or not you need to series of bytes. – moinudin Dec 28 '10 at 19:42
  • 7
    When using JSON you don't have to implement this interface and can simply send that string.. so Im still not sure why to use this interface when you can use JSON. – CodeMonkey Aug 29 '16 at 07:21
  • 1
    @YonatanNir I'm not sure why one would use JSON when MsgPack, Avro, Thrift, or Protobuf are better for IO transfer. – OneCricketeer Apr 23 '18 at 02:51
  • @cricket_007 what makes them better? And what is the difference between what they are sending and what is being sent as a JSON? – CodeMonkey Apr 23 '18 at 07:09
  • 1
    @YonatanNir A Strictly defined schema is better. And JSON is meant to be human readable, while binary encoded formats are far more efficient over the wire – OneCricketeer Apr 23 '18 at 07:10
  • @cricket_007 OK got ya. I guess there is plenty of overhead with a JSON string to make it readable with all the tags and what not.. – CodeMonkey Apr 23 '18 at 07:17
  • 1
    An important thing to note about Java Serialization is that it is JVM/version specific and for this, if not other (security) reasons, ill-advised to use as any kind of over-the-socket protocol (cite: Log4J 1.2 abandonment of serialized Java - which in later versions, LogBack ... to JSON k/v String pairs). Within the JVM for things like deep-cloning and other purposes, it is fine otherwise if not slower than native Java methods for data manipulation. – Darrell Teague Jul 09 '18 at 17:35
  • 1
    @DarrellTeague It is not JVM or version specific. It is specifically designed not to be. Do you have a reference link to this Log4J problem? I think it’s far more likely that the intended stability of Java serialization works as designed, and that Log4J developers misunderstood how to use serialization properly. – VGR Dec 21 '18 at 20:38
  • have read many times the definitions of what serialization is but I think this is the one what I am gonna remember through and preach to people. Thank you. – nightfury Dec 28 '18 at 16:52
  • @VGR - The comment was out-of-context. Yes, Java Serialization is 'standard' across JVMs/versions but ... the point was that two given serialized classes, created from different JVM versions for example, can be incompatible such as if trying to deserialize a Java v8 class in Java v7. That's the Java-specific reference. The Log4J devs have abandoned the original serialized-object-over-socket implementation. https://cxsecurity.com/issue/WLB-2017040112 – Darrell Teague Jan 02 '19 at 01:35
  • @DarrellTeague I literally just wrote a test program that serializes an object using Java 7, then deserializes it with Java 11. No special code required. What you’ve linked to is a [known security vulnerability inherent in deserialization.](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/package-summary.html) It’s also a known security vulnerability for all other languages capable of deserialization. It has nothing to do with Java versions. – VGR Jan 03 '19 at 16:08
  • @VGR - The reverse can be the issue.. Java 11 serialized class attempted to be deserialized in Java 7 for example. – Darrell Teague Jan 07 '19 at 13:29
  • @DarrellTeague That is not true. I just proved it by serializing an object in Java 11 and reading it in Java 7. [The serialization specification](https://docs.oracle.com/en/java/javase/11/docs/specs/serialization/index.html) is a stable specification. (Perhaps you were thinking of compiled .class files; it is certainly true that a Java 11 .class file won’t be readable in Java 7, unless the compiler was given `-target 7` or `--release 7`.) – VGR Jan 07 '19 at 14:53
  • @VGR - it all depends. If for example, a library (Swing is notorious for example) class is serialized in one Java version, its core implementation may have changed in other. For same class-name, etc ... if SerialVersionUID changed as a result of the hash for example, it will be considered a different class (even with same name from same core package for example) and fail deserialization. If the SerialVersionUID was not set, the generation of it can be different between JVM compilers/implementations and for the otherwise same class exactly, again can fail to deserialize. – Darrell Teague Jan 09 '19 at 04:00
  • 1
    @DarrellTeague Sure, but that’s not caused by different JVMs, it’s caused by using different classes. In fact, every Swing component’s documentation says: “**Warning:** Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing.” The warning is there because normally, serializable classes in Java SE do in fact take responsibility for serialized compatibility between versions. – VGR Jan 09 '19 at 05:11
  • Probably you mean the #3 point "it has nothing to do with security" to say it is not a security feature, but since it is a source of security flaws then there is a relationship, just not a good one. [Raedwald's answer](https://stackoverflow.com/a/53889695/217324) is the correct one here. – Nathan Hughes Jan 09 '19 at 16:17
  • What would be the impact on the performance if we don't implement Serializable? – Jack Sep 06 '20 at 12:28
107

The answer to this question is, perhaps surprisingly, never, or more realistically, only when you are forced to for interoperability with legacy code. This is the recommendation in Effective Java, 3rd Edition by Joshua Bloch:

There is no reason to use Java serialization in any new system you write

Oracle's chief architect, Mark Reinhold, is on record as saying removing the current Java serialization mechanism is a long-term goal.


Why Java serialization is flawed

Java provides as part of the language a serialization scheme you can opt in to, by using the Serializable interface. This scheme however has several intractable flaws and should be treated as a failed experiment by the Java language designers.

  • It fundamentally pretends that one can talk about the serialized form of an object. But there are infinitely many serialization schemes, resulting in infinitely many serialized forms. By imposing one scheme, without any way of changing the scheme, applications can not use a scheme most appropriate for them.
  • It is implemented as an additional means of constructing objects, which bypasses any precondition checks your constructors or factory methods perform. Unless tricky, error prone, and difficult to test extra deserialization code is written, your code probably has a gaping security weakness.
  • Testing interoperability of different versions of the serialized form is very difficult.
  • Handling of immutable objects is troublesome.

What to do instead

Instead, use a serialization scheme that you can explicitly control. Such as Protocol Buffers, JSON, XML, or your own custom scheme.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
  • 4
    not much of an expert at that level but feel you've got a point. – nightfury Dec 28 '18 at 16:59
  • 3
    I think it's the best answer! – jjanczur Mar 26 '20 at 10:28
  • 1
    The answer we need! Thanks. – Aviral Verma Oct 31 '20 at 16:09
  • What about this Sonar rule https://rules.sonarsource.com/java/RSPEC-1948 - stating that most J2EE frameworks flush to disk on heavy load. Sounds outdated to me, but does someone know more? – Hannes Schneidermayer Mar 16 '21 at 10:38
  • 1
    The only way so far that I know for your app to survive Tomcat restart is to implement serialization on all items stored in session scope beans. Right? I can guess there is another way but way back some years ago that was legal way to go. – horvoje Sep 11 '21 at 17:59
  • 1
    @horvoje the answer to that is, don't use old fashioned JEE features and approaches. A web server needs only a token (or cookie) from the client to indicate the session. Any actually necessary session data can be persisted just like any other data, in a DB. Any storage in the webserver is just caching to improve performance. – Raedwald Sep 12 '21 at 09:23
53
  1. Implement the Serializable interface when you want to be able to convert an instance of a class into a series of bytes or when you think that a Serializable object might reference an instance of your class.

  2. Serializable classes are useful when you want to persist instances of them or send them over a wire.

  3. Instances of Serializable classes can be easily transmitted. Serialization does have some security consequences, however. Read Joshua Bloch's Effective Java.

roottraveller
  • 7,942
  • 7
  • 60
  • 65
Steve Emmerson
  • 7,702
  • 5
  • 33
  • 59