Java Serializable: Must E be serializable in ArrayList<E>? - java

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.

Related

Are there some objects or data types that are automatically serialized by Java (without having to implement Serializable)?

I learned about implementing Serializable in school but it was never mentioned what, if any, objects are already doing this in Java. So my question is in the title "Are there some objects or data types that are automatically serialized by Java (without having to implement Serializable)?" and if so what are they are what is the reasoning behind it?
Javadoc is clear (emphasis is mine):
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.
But to answer to :
"Are there some objects or data types that are automatically
serialized by Java (without having to implement Serializable)?"
The answer is yes as the Javadoc adds that :
All subtypes of a serializable class are themselves serializable.
Here is a more detailed answer :
1) Primitives are de facto serializable.
2) A very important number of JDK classes implement Serializable. Which makes sense as these cannot be modified by clients and could so not be serialized. Here is the "Uses of Interface java.io.Serializable" generated in the javadoc. The list is huge.
3) Every array type implements the interfaces Cloneable and java.io.Serializable for exactly the same reason that other JDK classes are.(JLS 10.1 Array Types).
4) All subtypes of a serializable class are themselves serializable.
For example javax.swing.JComponent that is the base class for all Swing components except top-level containers implements Serializable :
public abstract class JComponent extends Container implements Serializable,...{...}
As a consequence, its child classes don't need to implement directly Serializable and indeed the very most of them don't do it.
For example :
public abstract class AbstractButton extends JComponent implements ItemSelectable, SwingConstants {...}
public class JButton extends AbstractButton implements Accessible {...}
public class JComboBox<E> extends JComponent{...}
We could see a similar thing for Number that is the base class for numeric values.
Number implements Serializable :
public abstract class Number implements java.io.Serializable {...}
And many subclasses implement Serializable by transitivity :
public final class Integer extends Number implements Comparable<Integer> {...}
public final class Float extends Number implements Comparable<Float> {...}
But note that the subclasses of classes implementing Serializable may also explicitly implement java.io.Serializable such as :
public class AtomicInteger extends Number implements java.io.Serializable {...}
It is probably done to make the information more explicit in the source code.
But it could also be helpful in case of code where the code is unstable and the hierarchy may change. Whatever the change, the class goes on to be serializable.
Yes. All array types are automatically serializable. JLS #10.1

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)

When saving a Serializable object, does everything referenced need to be Serializable too?

This may be obvious, but I'm not quite getting my head around Serialization:
I have a single object which holds the state of my application. This object references multiple other objects.
eg
ApplicationState implements Serializable
private ArrayList<SomeApplicationObjects>
private AnApplicationObject
private AnotherObject
All of these objects (someApplicationObjects, anApplicationObject, anotherObject) need to be serializable, as far as I understand.
But do objects THEY reference also need to be serializable? eg does SubObject here need to be serializable too? Does this essentially mean that every sub-object needs to be Serializable, recursively, from the ApplicationState down?
AnotherObject implements Serializable
private SubObject
Does this essentially mean that every sub-object needs to be Serializable, recursively
Assuming sub-object is the object you are using inside the class. Yes, the Objects used inside your Searializable type also be serializable.
Where as
All subtypes of a serializable class are themselves serializable
Yes, as reported in the javadoc of the interface 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. All subtypes of a serializable class are themselves serializable.
So if A has to be a serializable, subtypes of A (eg. B and C) have to be serializable too. So B and C should have also subtypes that are serializable, and so on..
As mention in java doc for serialization;
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.
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.
When traversing a graph, an object may be encountered that does not support the Serializable interface. In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object.
It is mandatory that all sub-object need to be serializable.

Serialization with Super class and Sub class

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.

Serializable a object properties too

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

Categories