Why does implementing Externalizable need a default public constructor? - java

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.

Related

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.

How does Externalizable differ from Serializable? [duplicate]

This question already has answers here:
What is the difference between Serializable and Externalizable in Java?
(11 answers)
Closed 9 years ago.
I read that
Externalizable provides us writeExternal() and readExternal() method which gives us flexibility to control java serialization mechanism instead of relying on Java's default serialization.
But If i implement Serializable and override readObject(), writeObject(), then does not it also means the same that I am customizing serialization process?
How does it differ?
THanks.
Difference between Externalizable and Serializable
In case of Serializable, default serialization process is used. while in case of Externalizable custom Serialization process is used which is implemented by application.
JVM gives call back to readExternel() and writeExternal() of java.io.Externalizalbe interface for restoring and writing objects into persistence.
Externalizable interface provides complete control of serialization process to application.
readExternal() and writeExternal() supersede any specific implementation of writeObject and readObject methods.
Though Externalizable provides complete control, it also presents challenges to serialize super type state and take care of default values in case of transient variable and static variables in Java. If used correctly Externalizable interface can improve performance of serialization process.
So go for Externalizable interface
When you have special requirements for the serialization of an object. For example, you may have some security-sensitive parts of the object, like passwords, which you do not want to keep and transfer somewhere. Or, it may be worthless to save a particular object referenced from the main object because its value will become worthless after restoring.
Official docs on Bean Persistence
Implement writeObject when you need to exercise greater control over what gets serialized when you need to serialize objects that default serialization cannot handle, or when you need to add data to the serialization stream that is not an object data member. Implement readObject to reconstruct the data stream you wrote with writeObject.
Use the Externalizable interface when you need complete control over your bean's serialization (for example, when writing and reading a specific file format). To use the Externalizable interface you need to implement two methods: readExternal and writeExternal. Classes that implement Externalizable must have a no-argument constructor.

Java: What can and what can't be serialized?

If the Serializable interface is just a Marker-Interface that is used for passing some-sort of meta-data about classes in java - I'm a bit confused:
After reading the process of java's serialization algorithm (metadata bottom-to-top, then actual instance data top-to-bottom), I can't really understand what data cannot be processed through that algorithm.
In short and formal:
What data may cause the NotSerializableException?
How should I know that I am not supposed to add the implements Serializable clause for my class?
First of all, if you don't plan to ever serialize an instance of your class, there is no need to even think about serializing it. Only implement what you need, and don't try to make your class serializable just for the sake of it.
If your object has a reference (transitive or direct) to any non-serializable object, and this reference is not marked with the transient keyword, then your object won't be serializable.
Generally, it makes no sense to serialize objects that can't be reused when deserialized later or somewhere else. This could be because the state of the object is only meaningful here and now (if it has a reference to a running thread, for example), or because it uses some resource like a socket, a database connection, or something like that. A whole lot of objects don't represent data, and shouldn't be serializable.
When you are talking about NotSerializableException it is throw when you want to serialize an object, which has not been marked as Serializable - that's all, although when you extend non serializable class, and add Serializable interface it is perfectly fine.
There is no data that can't be serialized.
Anything your Serializable class has in it that is not Serializable will throw this exception. You can avoid it by using the transient keyword.
Common examples of things you can't serialize include Swing components and Threads. If you think about it it makes sense because you could never deserialize them and have it make sense.
All the primitive data types and the classes extend either Serializable directly,
class MyClass extends Serializable{
}
or indirectly,
class MyClass extends SomeClass{
}
SomeClass implements Serializable.
can be serialized. All the fields in a serializable class gets serialized except the fields which are marked transient. If a serializable class contains a field which is not serializable(not primitive and do not extend from serializable interface) then NotSerializableException will be thrown.
Answer to the second question : As #JB Nizet said. If you are going to write the instance of a class to some stream then and then only mark it as Serializable, otherwise never mark a class Serializable.
You need to handle the serialization of your own Objects.
Java will handle the primitive data types for you.
More info: http://www.tutorialspoint.com/java/java_serialization.htm
After reading the process of java's serialization algorithm (metadata bottom-to- top, then actual instance data top-to-bottom), I can't really understand what data cannot be processed through that algorithm.
The answer to this is certain system-level classes such as Thread, OutputStream and its subclasses which are not serializable. Explained very well on the oracle documents: http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html
Below is the abstract:
On the other hand, certain system-level classes such as Thread, OutputStream and its subclasses, and Socket are not serializable. Indeed, it would not make any sense if they were. For example, thread running in my JVM would be using my system's memory. Persisting it and trying to run it in your JVM would make no sense at all.
NotSerialisable exception is thrown when something in your serializable marked as serializable. One such case can be:
class Super{}
class Sub implements Serializable
{
Super super;
Here super is not mentioned as serializable so will throw NotSerializableException.
More practically, no object can be serialized (via Java's built-in
mechanism) unless its class implements the Serializable interface.
Being an instance of such a class is not a sufficient condition,
however: for an object to be successfully serialized, it must also be
true that all non-transient references it holds must be null or refer to
serializable objects. (Do note that that is a recursive condition.)
Primitive values, nulls, and transient variables aren't a problem.
Static variables do not belong to individual objects, so they don't
present a problem either.
Some common classes are reliably serialization-safe. Strings are
probably most notable here, but all the wrapper classes for primitive
types are also safe. Arrays of primitives are reliably serializable.
Arrays of reference types can be serialized if all their elements can be
serialized.
What data may cause the NotSerializableException?
In Java, we serialize object (the instance of a Java class which has already implemented the Serializable interface). So it's very clear that if a class has not implemented the Serializable interface, it cannot be serialized (then in that case NotSerializableException will be thrown).
The Serializable interface is merely a marker-interface, in a way we can say that it is just a stamp on a class and that just says to JVM that the class can be Serialized.
How should I know that I am not supposed to add the implements
Serializable clause for my class?
It all depends on your need.
If you want to store the Object in a database, you can
serialize it to a sequence of byte and can store it in the
database as persistent data.
You can serialize your Object to be used by other JVM working
on different machine.

With out implementing a Serializable interface is it possible to make a class persistable in java?

In Java we implement an interface Serializable that defines no method (also called a marker interface).
But suppose I have an interface without any method just like a Serializable interface, can I make it work just like that, meaning that I would be able to use my interface instead of the Serializable?
Thanks
Only Serializable will mark an object as being compatible with Java's built-in serialization machinery.
You can create other empty interfaces, but they won't mean the same thing. Each interface is distinct, even if it defines the same set of methods.
No. If you want to be able to use Java Serialization, your objects need to implement Serializable.
If you want to use other serialization tools, (ie: Hibernate, SimpleXML, XStream), that is always a possibility, but those generally involve adding annotations, xml files, or other configurations.
If you want your object be serializable it must implement java.io.Serializable.
You could also create your own interface or class that extend from Serializable and then another class/interface extend from that one.
No. Serializable is a special interface, and you can't use a different one with the built-in serialization mechanism. You could roll your own entire system, but it'd be a big job.
If you don't implement Serializable you will not be able to use Java serialization to persist it. But you are more than welcome to implement your own persistence that is not relying on Java serialization.
Serializable is called a marker, but only because classes like ObjectOutputStream and ObjectInputStream use the reflection API to check for it. There is no special magic there; if you wanted to implement your own alternative serialization strategy, you could also create your own interface and use that as the marker you wished to respect. Although, you should consider whether it would actually be better design to use the existing Java marker (Serializable). I believe some other alternatives to the built-in Object stream do this.
If you merely wish to take complete control over how your objects are serialized into bytes, you can do so without rewriting the ObjectXXXStream classes, by using Serializable subclass Externalizable. And in fact, this is commonly done, since the automatic serialization afforded by Serializable ungracefully dies with the smallest change to the SerialVersionUID, which, unless supplied, is calculated automatically from various signatures of the class - making Serializable unsuitable for must persistent storage, since most kinds of changes (i.e. during a routine upgrade) to the underlying class will prevent reloading the serialized data.

Why does ObjectOutputStream.writeObject not take a Serializable?

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.

Categories