Wondering if I need to implements serializable interface or not? - java

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.

Related

Why implement Serializable on models?

I noticed in Spring-boot a lot of people create models/entities and implement the Serialiazable interface.
public class ModelBase implements Serializable
I understand what it means to serialize data/classes as it enables you to save the state of a class (if I'm not wrong, to a file for instance).
But I believe this should be done only when necessary, but either way it seems people just tend to implement the interface.
Is there a different reason?
When your models or entities are meant to travel across several JVM's then you might want to consider implementing Serializable interface. You should do this with caution. You should also provide a a valid UUID for the class to be used during Serialization and vice versa.
Sample is
private static final long serialVersionUID = 9178661439383356177L;
And
According to JPA Spec:
If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface.
Also
When using serializable values it is possible to remove this redundancy by changing the entity class in two ways:
Make the entity class serializable, so it can be used in place of the value class.
Make the key fields transient, so they are not redundantly stored in the record.
https://docs.oracle.com/cd/E17277_02/html/collections/tutorial/SerializableEntity.html

Why to serialize model class

Many times I see a model class will implement Serializable, but is never serialized.
What is purpose here to implement Serializable?
If serialization is not used, what will I miss? Is there any effect in the way the code communicates?
public class Stock implements Serializable{
private int stockId;
private String stockCode;
private String stockName;
//Getter and setter
}
What is purpose here to implement Serializable?
Just a marker to indicate the possibility provided to clients of the class for serializing instances of them if they wish.
For example, if you instantiate Stock class and that you want to save Stock instances in a file, you can do it thanks to this marker. APIs (for example Jaxb or Java native serialization mechanism) rely generally on the implementation of this interface to serialize class.
If serialization is not used, what will I miss? Is there any effect in
the way the code communicates?
It's is not used, you have zero overhead or transformation in the communication of the instance since it is a marker interface. Only, when the serialization occurs, the communication of the instance changes.
Serializable is just a marker interface without overhead*.
If you want class A to implement serializable and class A contains field with type Stock, Stock should also implement serializable.
May be there will be no direct Stock class instance serializations. But it will be serialized via class A instance.
Also implementing is necessary if you want Stock instance to become an argument of
type foo(? extends Serializable param)

RMI marshal and serialization

In java using RMI to marshal an object that you are returning from the remote class do you just need to implement Serializable on that object? I have a class node with variables inside that i want to be returned. Do i just implement serializable? If so what about the class that is receiving the object? does its class need to implement serializable too?
example:
public class node implements Serializable{
//variables
//variables
public node(//arguments to constructor here){
}
}
The class that is being serialized needs to implement Serializable. The sending and receiving classes don't. Not sure why you would think otherwise.
If you have a class whose instances you want to serialize using built-in Java serialization, not only must it implement Serializable, all its instance variables must also implement Serializable, or be primitives, or be marked transient (i.e. you tell the JVM that it's okay for them to not get serialized).
If your class can't conform to these constraints for some reason, you can implement custom serialization behavior yourself by implementing Externalizable - then you take responsibility for writing out your object's state and reading it back on the other end.
I'm not sure whether I understand your question correctly or not, but ... if the serializable class has other objects as member variables, then better make them serializable also, otherwise better declare as transient to skip. does this answer your question?
if code inspector program is handy, you can have answer for such question very quickly without posting it
for your tip, only the object you wan to persist or transfer needs to implements Serializable, so the object can be reconstructed as the class structure through serializing/unserializing

Java Serialization and JavaBeans

Quick question, when marking an object as serializable, does it need to be a JavaBean? I mean, can you serialize an object that's not a JavaBean? Does it have any risk? Is it a good practice to always make an object a JavaBean if you intend to serialize it?
You are looking at it the wrong way. A Java Bean is any class that is
1) implements Serializable
2) Has a no-arg constructor
3) Has private members and setters/getters
So your question
marking an object as serializable, does it need to be a JavaBean?
has it backwards. Any class can be Serializable, by implementing the interface. Not all serializable classes define a Java Bean.
I mean, can you serialize an object that's not a JavaBean?
Yes.
Is it a good practice to always make an object a JavaBean if you
intend to serialize it?
It is good practice to design your classes with data encapsulation in mind. This means limiting access to fields directly, and using setters and getters where appropriate.
Of course, having a public no-arg constructor is not always necessary from an API point of view.
You really only need to follow the Java bean standard if you are going to use a library that depends on your classes being Java Beans.
Serializable is a marker Interface. Each Object you mark with the serializable interface can be sent trouh the wire or can be safed in a file. For example if you mark the class Foo with the serializable interface, you are able to safe the object state in a file and restore it later:
public class Foo implements java.io.Serializable{
public String name;
}
public main(){
Foo foo = new Foo();
foo.name="test";
try
{
FileOutputStream fileOut = new FileOutputStream("foo.file");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(foo);
}
}
That means it doesnt need to be a JavaBean. It could be a plain old java object, like the Foo Object example.
If you want to serialize an object of class, then that class need to implement serializable interface irrespective of it's bean (or) class with simple properties.
To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java.io.Serializable interface or its subinterface, java.io.Externalizable. Deserialization is the process of converting the serialized form of an object back into a copy of the object
This tutorial may help you
You can serialize any object that implements the Serializable interface, whether it's a JavaBean or not.
That said, the decision to make an object Serializable shouldn't be made lightly, because it locks in certain implementation details of the class thus reducing future flexibility.
See here for information on implementing Serializable.

Why not serialize abstract classes in Java?

I have read that generally abstract classes should not be made Serializable in Java. The subclasses should be serializable (with custom read, write methods if required, for eg. when abstract classes have fields).
What is the reason behind this? Why is it considered bad design?
Update1: I have an abstract class with some fields and three subclasses. As of now, I am using the following approach.
I have made all the subclasses serializable with custom read, write methods. In the abstract class I have the following methods.
void writeFields(ObjectOutputStream out)throws IOException { .... }
void readFields(ObjectInputStream in) throws IOException, ClassNotFoundException{ ... }
In the custom read, write methods in the subclasses I call these methods to (de) serialize the fields in the abstract class. Is this approach correct? Or is there a different better approach?
Update 2: I took Tom's advice and made my abstract class Serializable. (I want all subclasses to be Serializable and I have data in the abstract class) This is an aside, but just to complete the story I am using reflection to change final fields as advised by Jeremy Manson.
I think the reason is that if an Abstract class implements Serializable, there is no way to say that a sub type should NOT be Serializable. Better to let each concrete type declare for itself...
I don't know that it is necessarily bad design. Serialisation is effectively an implementation issue (note, Josh Bloch disagrees with me), so doesn't make sense for interfaces. If the abstract class has state, then you would want to make it serialisable. If it doesn't have state, there isn't really any reason to make it so.
Let's take an example. java.security.cert.Certificate is an abstract serialisable class, with a "type" serialisable field. If it wasn't serialisable it would not be possible for a subclass to be serialisable and set that field. You would be forced in to a hack.
Note that java.io.Serializable is a hack. It shouldn't have been an interface. An annotation (or language evolution like transient) would have been more appropriate.
As always, it's best to prefer composition to inheritance and not to make random class serialisable.
Let's take the oposite position. If you were to De-Serialize the object, what would be its type?
By definition, an abstract class can't be instantiated. If you can serialize it, that implies that it can also be deserialized and that would get you an instance of the abstract class. That contradicts the definition of an abstract class and therefore can't be done.
It's only bad design because it's a forced decision, what if you want a subclass that has non-serializable members.
That's why.
E.g. List is not Serializable, but every major list implementation is. (I know list is a Interface, but a abstract class with no members =/= a interface)
If abstract class contains important for serialization fields and you are not going to implement custom object reader/writer it is essential to declare that base class as Serializable.
Declaring base class (or interface) as Serializable makes all sub-classes Serializable including any transitive path.
Latter makes sense if you implement some framework: you ease life your users automatically propagating interface, otherwise you should document that you work with Serializable only or implement runtime checks for user supplied classes.
I added base class for entities (to unify naming standard, for fields like id, createdDate, updatedDate) and forgot to mark it as Serializable. As a result any Entity kept in session store (Redis) had null id values upon deserialization )) You don't want this.
UPDATE Serializable requires public no-arg constructor for deserialization. Declaration of inheritance doesn't create no-arg constructor for sub-classes nor for super-class, it's a users' chore. Superclass without default constructor breaks deserialization for all sub-classes ))
UPDATE 2 There is a way to declare that subclass is not designed for serialization even if it is inherited from base class that is Serialazable although it is runtime feature:
private void writeObject(ObjectOutputStream out) throws IOException
{ throw new NotSerializableException(); }
private void readObject(ObjectInputStream in) throws IOException
{ throw new NotSerializableException(); }

Categories