When I have Serializable in a class, do I need to add Serializable to all my objects within the class?
For example,
public class User implements Serializable{
private List<Role> role;
private Task task;
}
Do I need to add Serializable to Role and Task, too?
public class Task implements Serializable{
// ...
}
public class Role implements Serializable{
// ...
}
Yes, you do; if your classes Task and Role are not Serializable, you'll get a java.io.NotSerializableException if you try to serialize an instance of User.
Ofcourse, if Task or Role contain other non-primitive, non-transient fields, they would have to be Serializable too, etc.
That is the simplest option.
The other option is to make those fields tranisent and "override" writeObject and readObject to implement your own serialization for those classes. It is unlikely this is worth the extra effort.
BTW: If you have a nested class, the outer class needs to be Serializable as well as the nested class implicitly has a reference to it even if you don't use it. For this reason and others I suggest making nested classes static whenever possible.
Short answer: yes.
Each object wihtin your serializable class MUST be serializable by itself. Otherwise all properties can't be restored or whatever.
Furthermore, you will also get an exception when trying to serialize this object.
From doc
Classes that do not implement this interface will not have any of their state serialized or deserialized.
So yes.
Please read
Related
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.
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)
I have the following class containing the fields specified below. My question is, must Admin, Worker and all my other self-defined classes implement Serializable for MyClass to be Serializable?
public class MyClass implements java.io.Serializable {
private static final long serialVersionUID = 1L;
ArrayList<Admin> admins;
ArrayList<Worker> workers;
ArrayList<Manager> managers;
ArrayList<Secretary> secretaries;
ArrayList<Category> categories;
HashMap<Issue, HashMap<Category,Manager>> ManagedIssues;
private static MyClass instance;
...
}
My question is, must Admin, Worker and all my other self-defined classes implement Serializable for MyClass to be Serializable?
Yes. They have to be.
ArrayList is already implements Serializable interface by default. But you need to implement Serializable interface for the types you are using.
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. All subtypes of a serializable class are themselves serializable.
As others have stated, if a class is marked Serializable, then everything inside needs to be marked Serializable too.
But in this case also, you really need to make sure you limit mutability of internal state. In other words, when taking a mutable object (like ArrayList) in (a constructor or a setter) or returning it (in a getter), make copies to protect the internal state of MyClass. This is always a good practice but especially so with Serializable.
Yes.
If you don't want that stuff to be serialized, mark it as transient.
If you are making a class serializable, then you have to make sure that everything falling in that class is also serializable. So you must make them serializable first.
Yes, but only if thoses lists / map are not empty. In this case serialization mechanizm will try to serialize collections' content.
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.
My doubt is using Scenario 1 it is possible to achieve serialization . If I extend one abstract class which is serializable by many sub classes means , is this possible to achieve ?. As I tried with Scenario 2.
Serializable will be applicable for all beans or not,Please help me.
my doubt scenario 1 and scenario 2 will be same or different.
//method to send message ::: sendMsgs(SerializableObject)
Scenario 1:
public class EmailMaster implements Serializable
{
// setters and getters
}
Scenario 2:
public abstract class MessageBean implements Serializable
{
}
//whether EmailMaster and EmailEvent will become serializable ?
public class EmailMaster extends MessageBean
{
// setters and getters
public class EmailEvent extends MessageBean
{
// setters and getters
}
This should be Serialilzable. When you extend MessageBean, all extending classes of MessageBean be default inherit the Serializable interface from MessageBean abstract class.
I would advice to have unique serialVersionUID assigned in each extending(sub) classes.
EDIT: From Searialization perspective, scenario1 and sceanrio2 are not different but theoretically they are different as you are having an additional abstract class in sceario2, which can have more methods/attributes, which will also get available to the EmailMaster class.
In both the scenarios: sendMsgs(SerializableObject) should work. Make a decision between sceanrio1 and scenario2 based on the need of abstract class in between. If you don't need the abstract class for any other purpose, go with scenario1.
Serializable is inherited by all the subclasses of the abstract class as for any other interface:
If A implements Serializable, whatever class extends A will be Serializable
So both Scenarios will work but in any case a concrete Serializable class must have a no-args constructor. See the following Serializable Javadoc:
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.
All subtypes of a serializable class are themselves serializable. The
serialization interface has no methods or fields and serves only to
identify the semantics of being serializable.
To allow subtypes of non-serializable classes to be serialized, the
subtype may assume responsibility for saving and restoring the state
of the supertype's public, protected, and (if accessible) package
fields. The subtype may assume this responsibility only if the class
it extends has an accessible no-arg constructor to initialize the
class's state. It is an error to declare a class Serializable if this
is not the case. The error will be detected at runtime.
Moreover, regarding the Serial Version ID of the object:
The serialization runtime associates with each serializable class a
version number, called a serialVersionUID, which is used during
deserialization to verify that the sender and receiver of a serialized
object have loaded classes for that object that are compatible with
respect to serialization. If the receiver has loaded a class for the
object that has a different serialVersionUID than that of the
corresponding sender's class, then deserialization will result in an
InvalidClassException. A serializable class can declare its own
serialVersionUID explicitly by declaring a field named
"serialVersionUID" that must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a
default serialVersionUID value for that class based on various aspects
of the class, as described in the Java(TM) Object Serialization
Specification. However, it is strongly recommended that all
serializable classes explicitly declare serialVersionUID values, since
the default serialVersionUID computation is highly sensitive to class
details that may vary depending on compiler implementations, and can
thus result in unexpected InvalidClassExceptions during
deserialization.
Try
Serializable emailMaster = new EmailMaster();
If it works then EmailMaster is-a Serializable. AFAIK, that definitely should work.