Serialization with Super class and Sub class - java

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.

Related

How to make a Generic Type Serializable?

SonarQube gives the following bug:
Make "type" transient or serializable.
On the following class:
#XmlRootElement
public class InsuredAmount<T extends IAType> implements Serializable {
private static final long serialVersionUID = 1L;
private T type;
}
IAType is an interface:
public interface IAType {
}
With various enum implementations, like:
public enum OneIAType implements IAType, Serializable {
GENERIC
}
The class is used in a REST interface, so it should be Serializable.
My Questions:
1. I don't think marking the type as transient is a good idea, because I am transferring this class via a REST interface. Can it lead to a problem if I mark this type as transient?
2. How can I make the type serializable?
Can it lead to a problem if I mark this type as transient?
Depends if you need the value in the field after you deserialize the instance. If you do, you can mark it transient, but you need some other way to transfer the necessary information to reconstruct the value of type at the far end.
How can I make the type serializable?
Declare the type variable as an intersection type:
<T extends IAType & Serializable>
Edit: it appears that this suggestion isn't recognised by SonarQube as a serializable type.
It says in the question that the implementations of the interface are enums; that suggests that an alternative way to express the bound would be:
<T extends Enum<T> & IAType>
Note that all enums are implicitly serializable, so Serializable doesn't have to be in the intersection type explicitly.
It turns out that this way works, whereas the first way does not: references of both types can be assigned to a variable of type Serializable. (Perhaps it is a bug in SonarQube?)

Why do you need to redefine serialVersionUID if you extends a class which implements Serializable "down the line"?

For one of my projects, I need to define a new exception which extends ProviderMismatchException.
From the javadoc link, you can see that this exception:
extends IllegalArgumentException, which
extends RuntimeException, which
extends Exception, which
extends Throwable.
All of them define their own static final serialVersionUID except for Throwable which adds the private modifier.
Now, if you implement an interface Foo, then all inherited classse also implement that interface, and this stands for Serializable as well; however, why do subclasses in the JDK redefine it for each subclass? What is the danger of not defining it again for inherited classes?
The serialVersioUID is a static long value, thus it won't be inherited through the class hierarchy.
You need this to indicate if a prior serialized instance of a class has the same version as the current implementation or not.
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.
For Details see here:
What is a serialVersionUID and why should I use it?

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.

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

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.

Java Serialization Issue

When I serialize the abstract class does the inheriting subclasses will also be serialize?
Does this include the members of abstract class and its subclasses?
public abstract class RootClass implements Serializable{
Object data;
}
public class SubClassA extends RootClass{
Object dataA;
}
public class SubClassB extends RootClass{
Object dataB;
}
Now when I instantiate class SubClassA and SubClassB and I will serialize those instances it is possible?
Will it include members of subclasses and root class?
Not sure if I understand the question. I'll try to answer anyway.
When you declare an abstract class Serializable, this interface is also inherited by subclasses, so they are considered Serializable and will also have to be made serializable (if you do nothing, the default serialization mechanism will be applied to it, which may or may not work).
You only serialize object instances, not classes.
The default serialization serializes fields of a parent class, too, but only if that parent class is also Serializable. If not, the parent state is not serialized.
If you serialize an object of an abstract class' subclass, and the abstract class is Serializable, then all fields in that abstract parent class will also be serialized (the usual exceptions apply, such as transient or static fields).
Serialization is for 'objects' and saving their state and not for the classes. Since you cannot create instances for abstract classes, there is no point in discussing whether they can be serialized in the first place.
When you instantiate an object of a certain class, its data is comprised of two parts: fields defined by its class and fields defines by superclasses. Mind you, not all inherited fields are accessible, only those defined as protected or public (or unmodified when in the same package).
If the object's class is Serializable, its fields will be serialized (unless marked transient), and the same is true for inherited fields. In your case, an instance of SubClassA will contain both 'data' and 'dataA', and because both class and subclass are Serializable, both fields will be serialized. After deserialization, both fields should be accessible.

Categories