Why does ObjectOutputStream.writeObject not take a Serializable? - java

Why does ObjectOutputStream.writeObject(Object o) not take a Serializable? Why is it taking an Object?

This is because writeObject in ObjectOutputStream overrides the method in the ObjectOutput interface which does not require that the object be Serializable.
The ObjectOutput interface specifies methods that allow objects to be written to a stream or underlying storage, but this may be achieved by a process other than serialization. The ObjectOutputStream implements this functionality, but requires serializable objects. However, it cannot modify the signature of the interface that it implements.

It should be ObjectOutputStream.writeObject(serializable) rather than ObjectOutputStream. writeObject(Object). It is a proper use case where a marker interface like Serializable should have been used but unfortunately not. This would have made it possible the very real benefit of compile-time type checking instead of failing at runtime if the object does not implement Serializable interface.
I would like to take this opportunity to mention what Joshua Bloch has mentioned in his book Effective java:
A marker interface is an interface that contains no method
declarations, but merely designates (or “marks”) a class that
implements the interface as having some property. For example,
consider the Serializable interface. By implementing this interface, a
class indicates that its instances can be written to an
ObjectOutputStream (or “serialized”).
In the case of the Serializable marker interface, the ObjectOutputStream.write(Object) method will fail if its argument does not
implement the interface. Inexplicably, the authors of the
ObjectOutputStream API did not take advantage of the Serializable
interface in declaring the write method. The method’s argument type
should have been Serializable rather than Object. As it stands, an
attempt to call ObjectOutputStream.write on an object that doesn’t
implement Serializable will fail only at runtime, but it didn’t have
to be that way.

Related

Wondering if I need to implements serializable interface or not?

I am new to MyBatis, I saw some code which define model as
public class model implement serializable {
****
}
but some codes simple define without serializable interface.
I am wondering which is better? Serializable is an empty interface actually.
You need to define the Serializable interface if you plan to serialize instances of your class. It's that simple.
Many do it out of routine, but the entire point of Serializable is that some classes can NOT be serialized correctly. By making you implement this interface, you make the conscious decision that your class, in fact, can be serialized.
Mybatis don't require serialization. It dynamically calls constructor after executing query and create bean objects.
So answer is no you don't need to implement Serializable interface.
Serializable is a marker interface and has no method. It just tell jvm that you are intrested to serialize the type and rest will be done automatically.

Serialization not implemented?

What I understand is that I can implement Serializable interface to make my object serializable.
But I don't get where is writeObject method implemented when Serializable is an interface, so it doesn't contain implementation of methods, just a definition?
As you already noticed, the Serializable is a Marker Interface and does not have any methods to implement. Implementing Serializable is just a note that this one is eligible for serialization which is handled using ObjectOutputStream.
Methods you mentioned need to be implemented in a class implementing the Serializable interface and will be picked up automatically. Since there is no obligation for implementing them, they are not included in the interface.
http://docs.oracle.com/javase/8/docs/platform/serialization/spec/serial-arch.html#a4539
Tough all the answers posted so far are right, I wish to add some extra comments:
java.io.Serializable was already part of the Java 1.1 API (among the first versions of Java), and was meant as an easy way for the programmer to mark any class to have a special behaviour.
According to OOP principles, that should have been done through a regular interface, which is what you (and me, and any other programmer) would have expected. Something like this:
public interface Serializable<E>
{
public E read(DataInput input) throws IOException;
public void write(DataOutput output) throws IOException;
}
But, since there are many classes in Java which needed to be serialized, the Java Language designers wished to save troubles to programmers, by some kind of mechanism through which serialization would be performed automatically. But how?
Through an abstract class? Nope. That would have prevented any custom class to have its own hierarchy (since in Java there is only single inheritance).
Making java.lang.Object serializable? Neither so, because that would have prevented programmers to decide which class should be serializable and which should not.
On top of all, there was a hughe problem: Note that method read is supposed to create and return an object of class E from a DataInput stream. An abstract class just can not create instances of its subclasses whithout further information (the abstract class does not know which is the applied subclass).
So, they decided to pass over the OOP and offer Serialization as a special non-oop feature of the serialization classes ObjectOutputStream/ObjectInputStream (credits to EJP for this detail) in the form of a "dummy" interface recognizable by them, at the price of adding somehow some confussion to the class definitions, because an interface with no methods is nonsense (Same approach they adopted for java.lang.Cloneable).
Actually, it adds even more confussion, because custom serialization must be done by implementing private methods readObject and writeObject (as specified by ObjectOutputStream), which is a feature non describible in terms of a Java interface.
Nowadays, these kind of marking can be done through annotations. Well, think of Serializable as an interface which should have been an annotation, but still remains as an interface for those -endless- compatibility reasons.

Do Interfaces provide specific meaning to objects in Java

I have a doubt about Interfaces in JAVA:
When a class implements an interface, does anything happen to it if it does not implement its methods? Merely implementing the interface , does it provide any change of meaning to the class ?
For example I have two classes, Test1 and Test2
public class Test1 implements Serializable {
}
public class Test2 {
}
Except for the fact that Test1 implements Serializable, the classes Test1 and Test2 are identical. In that case would there be any difference between the functionalities/properties of objects of Test1 and Test2? Would it be possible to break down objects of Test1 class into bytes (just because class Test1implements Serializable)?
If yes, then that means implementing an interface provides some additional meaning to the objects of that class?
Straight from documentaion of Serializable -
Serializability of a class is enabled by the class implementing the
java.io.Serializable interface. Classes that do not implement this
interface will not have any of their state serialized or deserialized.
The serialization interface has no methods or fields and serves only
to identify the semantics of being serializable.
Link
Q1> In that case would there be any difference between the functionalities/properties of objects of Test1 and Test2?
Serializable is marker interface, which means there no method or field.
Q2> Would it be possible to break down Objects of Test1 class into bytes (just because class Test1 implements Serializable?
Yes.
Q3> If yes, then that means implementing an interface provides some additional meaning to the objects of that class?
Object Serialization produces a stream with information about the Java
classes for the objects which are being saved. For serializable
objects, sufficient information is kept to restore those objects even
if a different (but compatible) version of the implementation of the
class is present.
Thhe class can optionally define the following methods:
A writeObject method to control what information is saved or to
append additional information to the stream
A readObject method either to read the information written by the
corresponding writeObject method or to update the state of the object
after it has been restored
A writeReplace method to allow a class to nominate a replacement
object to be written to the stream
Link
It depends on the definition of the interface you decide to implement.
In the example you took one of the classes implemented serializable interface; it being a marker interface you did not have to overload any of its method. But there is as you know a difference between the two classes, while objects of Test1 class can be converted to stream of bytes for external storage such feature is not available for Test2 objects. Also, there is a serialId class member which Test1 has but Test2 does not.
This was a specific case; but lets say the interface you implemented had abstract methods, then in this case Test1 class either had to also be an abstract class or it had to provide a concrete definition to those abstract methods of the interface. In such a scenario Test1 and Test2 classes would have varied a lot from each other. FYI,The interface body can contain abstract methods, default methods, and static methods.
In Java 8+ it's possible for an interface to provide a default method. For example 13.5.6-1. Adding A Default Method (which means an interface can add method implementations),
interface Painter {
default void draw() {
System.out.println("Here's a picture...");
}
}
However, Serializable is a marker interface (and Wikipedia says, in part) the mere presence of such an interface indicates specific behavior on the part of the implementing class. You might want to compare it to Externalizable.
An interface, in its most basic form, is a set of empty methods which define some core functions. A class which implements an interface will be required to include all of its methods.
However, interface Serializable does not have any methods. It simply states "this object can be serialized," and they sometimes rely on other special methods (readObject(), writeObject(), etc.) for handling.
Here's a quote from Javadocs:
Serializability of a class is enabled by the class implementing the
java.io.Serializable interface. Classes that do not implement this
interface will not have any of their state serialized or deserialized.
The serialization interface has no methods or fields and serves only
to identify the semantics of being serializable.
Therefore a class can only be serialized if it implements interface Serializable.

Why classes that implements Serializable interface implements none interface's methods?

I thought class that implements an interface must implement all of the interface's methods,why classes that implements Serializable interface implements none interface's methods ?
Some interfaces act simply as markers for classes. Serializable is one of them. The methods are there only in case your object requires special handling in order to be serialized and deserialized.
Because Serializable is only a "marker" interface for object serialization and has no methods defined. From the Javadoc:
The serialization interface has no methods or fields and serves only
to identify the semantics of being serializable.
And from SDN:
An object is marked serializable by implementing the
java.io.Serializable interface, which signifies to the underlying API
that the object can be flattened into bytes and subsequently inflated
in the future.

Why does implementing Externalizable need a default public constructor?

We don't need it if we're implementing Serializable. So why this difference? How does it relate to the actual mechanism of Serialization?
A thorough explanation (although the grammar of the article might be improved) can be found on http://www.jusfortechies.com/java/core-java/externalization.php . The short answer, for future reference in case the linked page goes away:
Externalizable is an interface extending Serializable. Contrary to Serializable, though, objects are not restored by just reading the serialized bytestream, but the public constructor is called and only once the object is thus created, its state is restored. This makes restoring more efficient.
Edit: See also What is the difference between Serializable and Externalizable in Java? .
This is primarily used for caching purposes. In order to deserialize across streams, you will need to spell out how you want your object to be deserialized, hence the two methods provided by the contract in Externalizable interface: writeExternal and readExternal. Note that Externalizable extends Serializable, so you don't necessarily need to implement Serializable interface (although it's a marker interface and there are no methods to be actually implemented).
For a sample implementation, have a look at MimeType.
A public no-arg constructor is needed while using Externalizable interface.
Because in case of Serializable
readObject reads the required information from the ObjectInputStream
Serialization uses reflection mechanism to get the necessary fields and their corresponding values.
Serializable serializes all the data members (except static and transient).
But in case of Externalizable
No reflection mechanism used.
User doesn't serializes all data members.That's why to fetch values of the members which are not externalized public no arg constructor is required.

Categories