Serialization Java Interview Questions | Eklavya Online

Serialization Java Interview Questions

This is usefull in domain or value object class to compare different object fields in an equals method

public class DomainObject {

 

//protected because only inheriting domain classes can use it

protected boolean isPropertyEqual(Object compare1, Object compare2) {

// go here if compare1 is null, i.e. test cases 1 & 3

if (compare1 == null) {

if (compare2 != null) {

return false;

}

//go here if compare1 is not null, i.e. test cases 2 & 5

} else if (!compare1.equals(compare2)) {

return false;

}

 

return true;      //test cases 1 & 4

}

 

public static void main(String[] args) {

DomainObject d =  new DomainObject();

Print(d.isPropertyEqual(null, null));  //test case 1

Print(d.isPropertyEqual(“abc”, null)); //test case 2

Print(d.isPropertyEqual(null, “abc”)); //test case 3

Print(d.isPropertyEqual(“abc”, “abc”));//test case 4

Print(d.isPropertyEqual(“abc”, “cba”));//test case 5

}

 

public static void Print(boolean bol){

System.out.println(bol);

}

}

 

 

The above class must be abstract. It was not tagged abstract to demo via the main() method by creating a new DomainObject().

The above method can be used in an extending class like

public class Security extends DomainObject implements Serializable {

 

private String id;

//skipping other methods like getter/setter, toString, etc

 

public boolean equals(Object obj) {

if (this == obj) {

return true;

}

if (!(obj instanceof Security)) {

return false;

}

 

//calling super class handy method we just created

return isPropertyEqual(this.id, ((Security) obj).getId());

}

 

public int hashCode() {

return id.hashCode();

}

}

This is usefull in domain or value object class to compare different object fields in an equals method

public class DomainObject {

 

//protected because only inheriting domain classes can use it

protected boolean isPropertyEqual(Object compare1, Object compare2) {

// go here if compare1 is null, i.e. test cases 1 & 3

if (compare1 == null) {

if (compare2 != null) {

return false;

}

//go here if compare1 is not null, i.e. test cases 2 & 5

} else if (!compare1.equals(compare2)) {

return false;

}

 

return true;      //test cases 1 & 4

}

 

public static void main(String[] args) {

DomainObject d =  new DomainObject();

Print(d.isPropertyEqual(null, null));  //test case 1

Print(d.isPropertyEqual(“abc”, null)); //test case 2

Print(d.isPropertyEqual(null, “abc”)); //test case 3

Print(d.isPropertyEqual(“abc”, “abc”));//test case 4

Print(d.isPropertyEqual(“abc”, “cba”));//test case 5

}

 

public static void Print(boolean bol){

System.out.println(bol);

}

}

 

 

The above class must be abstract. It was not tagged abstract to demo via the main() method by creating a new DomainObject().

The above method can be used in an extending class like

public class Security extends DomainObject implements Serializable {

 

private String id;

//skipping other methods like getter/setter, toString, etc

 

public boolean equals(Object obj) {

if (this == obj) {

return true;

}

if (!(obj instanceof Security)) {

return false;

}

 

//calling super class handy method we just created

return isPropertyEqual(this.id, ((Security) obj).getId());

}

 

public int hashCode() {

return id.hashCode();

}

}

In order to assign a superclass object in a variable to a subclass,one needs to do explicit casting.

For example:Person person=null;

Man man = (Man)person;

An automatic casting takes place when we typecast a object in subclass as parent class object.

Define Externalizable.

Externalizable is coined as an Interface

It extends the Serializable Interface.

It also sends data into the Streams.

Externalizable sends data in a Compressed Format.

Externalizable is having two methods,for e.g. writeExternal(ObjectOuput out) & readExternal(ObjectInput in)

Serialization is the conversion of an object to a series of bytes, so that the object can be easily saved to persistent storage or streamed across a communication link. The byte stream can then be deserialised – converted into a replica of the original object.

Serialization is the process of writing the state of an object to a byte stream. Deserialization is the process of restoring these objects.

A transient variable is a variable that may not be serialized.

Transient: The transient modifier applies to variables only and it is not stored as part of its object’s Persistent state. Transient variables are not serialized. Volatile: Volatile modifier applies to variables only and it tells the compiler that the variable modified by volatile can be changed unexpectedly by other parts of the program.

The marker interface is a design pattern, used with languages that provide run-time type information about objects. It provides a way to associate metadata with a class where the language does not have explicit support for such metadata. To use this pattern, a class implements a marker interface, and code that interact with instances of that class test for the existence of the interface. Whereas a typical interface specifies methods that an implementing class must support, a marker interface does not do so. The mere presence of such an interface indicates specific behavior on the part of the implementing class. There can be some hybrid interfaces, which both act as markers and specify required methods, are possible but may prove confusing if improperly used. Java utilizes this pattern very well and the example interfaces are:

  • io.Serializable – Serializability of a class is enabled by the class implementing the java.io.Serializable interface. The Java Classes that do not implement Serializable interface will not be able to serialize or deserializ their state. 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.
  • rmi.Remote – The Remote interface serves to identify interfaces whose methods may be invoked from a non-local virtual machine. Any object that is a remote object must directly or indirectly implement this interface. Only those methods specified in a “remote interface”, an interface that extends java.rmi.Remote are available remotely.
  • lang.Cloneable – A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class. Invoking Object’s clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown.
  • servlet.SingleThreadModel – Ensures that servlets handle only one request at a time. This interface has no methods.
  • util.EvenListener – A tagging interface that all event listener interfaces must extend.
  • The “instanceof” keyword in java can be used to test if an object is of a specified type. So this keyword in combination with Marker interface can be used to take different actions based on type of interface an object implements.

An object must implement the Serializable or Externalizable interface before it can be written to a stream as an object.

In Java, if the super class of a class is implementing Serializable interface, it means that it is already serializable. Since, an interface cannot be unimplemented, it is not possible to make a class non-serializable. However, the serialization of a new class can be avoided. For this, writeObject () and readObject() methods should be implemented in your class so that a Not Serializable Exception can be thrown by these methods. And, this can be done by customizing the Java Serialization process. Below the code that demonstrates it

class MySubClass extends SomeSerializableSuperClass {

private void writeObject(java.io.ObjectOutputStream out)

throws IOException {

throw new NotSerializableException(“Can not serialize this class”);

}

private void readObject(java.io.ObjectInputStream in)

throws IOException, ClassNotFoundException {

throw new NotSerializableException(“Can not serialize this class”);

}

private void readObjectNoData()

throws ObjectStreamException; {

throw new NotSerializableException(“Can not serialize this class”);

}

}

Declaring an explicit serialVersionUID field in your classes saves some CPU time only the first time the JVM process serializes a given Class. However the gain is not significant, In case when you have not declared the serialVersionUID its value is computed by JVM once and subsequently kept in a soft cache for future use.

Serialization is required for a variety of reasons. It is required to send across the state of an object over a network by means of a socket. One can also store an object’s state in a file. Additionally, manipulation of the state of an object as streams of bytes is required. The core of Java Serialization is the Serializable interface. When Serializable interface is implemented by your class it provides an indication to the compiler that java Serialization mechanism needs to be used to serialize the object.

In case, Serialization is not used, Java objects can be serialized by many ways, some of the popular methods are listed below:

  • Saving object state to database, this is most common technique used by most applications. You can use ORM tools (e.g. hibernate) to save the objects in a database and read them from the database.
  • Xml based data transfer is another popular mechanism, and a lot of XML based web services use this mechanism to transfer data over network. Also a lot of tools save XML files to persist data/configurations.
  • JSON Data Transfer – is recently popular data transfer format. A lot of web services are being developed in JSON due to its small footprint and inherent integration with web browser due to JavaScript format.

This is one of top serialization questions that is asked in many big companies to test your in-depth understanding of serialization. Serializable is a marker interface therefore you are not forced to implement any methods, however Externalizable contains two methods readExternal() and writeExternal() which must be implemented. Serializable interface provides a inbuilt serialization mechanism to you which can be in-efficient at times. However Externilizable interface is designed to give you greater control over the serialization mechanism. The two methods provide you immense opportunity to enhance the performance of specific object serialization based on application needs. Serializable interface provides a default serialization mechanism, on the other hand, Externalizable interface instead of relying on default Java Serialization provides flexibility to control this mechanism. One can drastically improve the application performance by implementing the Externalizable interface correctly. However there is also a chance that you may not write the best implementation, so if you are not really sure about the best way to serialize, I would suggest your stick to the default implementation using Serializable interface.

This is one of a difficult and tricky questions and answering this correctly would mean you are an expert in Java Serialization concept. In an already serialized object, the most challenging task is to change the structure of a class when a new field is added or removed. As per the specifications of Java Serialization, addition of any method or field is considered to be a compatible change whereas changing of class hierarchy or non-implementation of Serializable interface is considered to be a non-compatible change. You can go through the Java serialization specification for the extensive list of compatible and non-compatible changes. If a serialized object need to be compatible with an older version, it is necessary that the newer version follows some rules for compatible and incompatible changes. A compatible change to the implementing class is one that can be applied to a new version of the class, which still keeps the object stream compatible with older version of same class. Some Simple Examples of compatible changes are:

  • Addition of a new field or class will not affect serialization, since any new data in the stream is simply ignored by older versions. the newly added field will be set to its default values when the object of an older version of the class is un marshaled.
  • The access modifiers change (like private, public, protected or default) is compatible since they are not reflected in the serialized object stream.
  • Changing a transient field to a non-transient field is compatible change since it is similar to adding a field.
  • Changing a static field to a non-static field is compatible change since it is also similar to adding a field.
  • Some Simple Examples of incompatible changes are:
  • Changing implementation from Serializable to Externalizable interface can not be done since this will result in the creation of an incompatible object stream.
  • Deleting a existing Serializable fields will cause a problem.
  • Changing a non-transient field to a transient field is incompatible change since it is similar to deleting a field.
  • Changing a non-static field to a static field is incompatible change since it is also similar to deleting a field.
  • Changing the type of a attribute within a class would be incompatible, since this would cause a failure when attempting to read and convert the original field into the new field.
  • Changing the package of class is incompatible. Since the fully-qualified class name is written as part of the object byte stream.

Java serialization is one of the most commonly misunderstood areas. Many developers still think its only used for saving objects on the file system

The transient keyword in Java is used to indicate that a field should not be serialized. Once the process of de-serialization is carried out, the transient variables do not undergo a change and retain their default value. Marking unwanted fields as transient can help you boost the serialization performance. Below is a simple example where you can see the use of transient keyword.

class MyVideo implements Serializable  {

private Video video;

private transient Image thumbnailVideo;

private void generateThumbnail()

{

// Generate thumbnail.

}

private void readObject(ObjectInputStream inputStream)

throws IOException, ClassNotFoundException

{

inputStream.defaultReadObject();

generateThumbnail();

}

}

Most of the times when you want to do a selective attribute serialization you can use Serializable interface with transient modifier for variables not to be serialized. However, use of Externalizable interface can be really effective in cases when you have to serialize only some dynamically selected attributes of a large object. Lets take an example, Some times when you have a big Java object with hundreds of attributes and you want to serialize only a dozen dynamically selected attributes to keep the state of the object you should use Externalizable interface writeObject method to selectively serialize the chosen attributes. In case you have small objects and you know that most or all attributes are required to be serialized then you should be fine with using Serializable interface and use of transient variable as appropriate.

Connected RowSet

A RowSet object may make a connection with a data source and maintain that connection throughout its life cycle, in which case it is called a connected rowset. A rowset may also make a connection with a data source, get data from it, and then close the connection. Such a rowset is called a disconnected rowset. A disconnected rowset may make changes to its data while it is disconnected and then send the changes back to the original source of the data, but it must reestablish a connection to do so. Example of Connected RowSet: A JdbcRowSet object is a example of connected RowSet, which means it continually maintains its connection to a database using a JDBC technology-enabled driver.

Disconnected RowSet

A disconnected rowset may have a reader (a RowSetReader object) and a writer (a RowSetWriter object) associated with it. The reader may be implemented in many different ways to populate a rowset with data, including getting data from a non-relational data source. The writer can also be implemented in many different ways to propagate changes made to the rowset’s data back to the underlying data source.Example of Disconnected RowSet: A CachedRowSet object is a example of disconnected rowset, which means that it makes use of a connection to its data source only briefly. It connects to its data source while it is reading data to populate itself with rows and again while it is propagating changes back to its underlying data source. The rest of the time, a CachedRowSet object is disconnected, including while its data is being modified. Being disconnected makes a RowSet object much leaner and therefore much easier to pass to another component. For example, a disconnected RowSet object can be serialized and passed over the wire to a thin client such as a personal digital assistant (PDA).

The Java variables declared as static are not considered part of the state of an object since they are shared by all instances of that class. Saving static variables with each serialized object would have following problems

  • It will make redundant copy of same variable in multiple objects which makes it in-efficient.
  • The static variable can be modified by any object and a serialized copy would be stale or not in sync with current value.

The default Java Serialization mechanism is really useful, however it can have a really bad performance based on your application and business requirements. The serialization process performance heavily depends on the number and size of attributes you are going to serialize for an object. Below are some tips you can use for speeding up the marshaling and un-marshaling of objects during Java serialization process.

  • Mark the unwanted or non Serializable attributes as transient. This is a straight forward benefit since your attributes for serialization are clearly marked and can be easily achieved using Serialzable interface itself.
  • Save only the state of the object, not the derived attributes. Some times we keep the derived attributes as part of the object however serializing them can be costly. Therefore consider calcualting them during de-serialization process.
  • Serialize attributes only with NON-default values. For examples, serializing a int variable with value zero is just going to take extra space however, choosing not to serialize it would save you a lot of performance. This approach can avoid some types of attributes taking unwanted space. This will require use of Externalizable interface since attribute serialization is determined at runtime based on the value of each attribute.
  • Use Externalizable interface and implement the readObject and writeObject methods to dynamically identify the attributes to be serialized. Some times there can be a custom logic used for serialization of various attributes.

From Sun FAQ Page: Many Collection implementations (including all of the ones provided by the JDK) will have a public clone method, but it would be mistake to require it of all Collections. For example, what does it mean to clone a Collection that’s backed by a terabyte SQL database? Should the method call cause the company to requisition a new disk farm? Similar arguments hold for serializable. If the client doesn’t know the actual type of a Collection, it’s much more flexible and less error prone to have the client decide what type of Collection is desired, create an empty Collection of this type, and use the addAll method to copy the elements of the original collection into the new one. Note on Some Important Terms

  • Synchronized means only one thread can modify a hash table at one point of time. Basically, it means that any thread before performing an update on a hashtable will have to acquire a lock on the object while others will wait for lock to be released.

Fail-fast is relevant from the context of iterators. If an iterator has been created on a collection object and some other thread tries to modify the collection object “structurally”, a concurrent modification exception will be thrown. It is possible for other threads though to invoke “set” method since it doesn’t modify the collection “structurally”. However, if prior to calling “set”, the collection has been modified structurally, “IllegalArgumentException” will be thrown

All standard implementations of collections List, Set and Map interface already implement java.io.Serializable. All the commonly used collection classes like java.util.ArrayList, java.util.Vector, java.util.Hashmap, java.util.Hashtable, java.util.HashSet, java.util.TreeSet do implement Serializable. This means you do not really need to write anything specific to serialize collection objects. However you should keep following things in mind before you serialize a collection object – Make sure all the objects added in collection are Serializable. – Serializing the collection can be costly therefore make sure you serialize only required data isntead of serializing the whole collection. – In case you are using a custom implementation of Collection interface then you may need to implement serialization for it.

The serialVersionUID represents your class version, and you should change it if the current version of your class is not backwards compatible with its earlier versions. This is extract from Java API Documentation

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.

Most of the times, we probably do not use serialization directly. In such cases, I would suggest to generate a default serializable uid by clicking the quick fix option in eclipse.

Yes, the serialization process can be customized. When an object is serialized, objectOutputStream.writeObject (to save this object) is invoked and when an object is read, ObjectInputStream.readObject () is invoked. What most people do not know is that Java Virtual Machine provides you with an option to define these methods as per your needs. Once this is done, these two methods will be invoked by the JVM instead of the application of the default serialization process. Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in)

throws IOException, ClassNotFoundException;

private void readObjectNoData()throws ObjectStreamException;

Serialization is a mechanism by which you can save or transfer the state of an object by converting it to a byte stream. This can be done in java by implementing Serialiazable interface. Serializable is defined as a marker interface which needs to be implemented for transferring an object over a network or persistence of its state to a file. Since its a marker interface, it does not contain any methods. Implementation of this interface enables the conversion of object into byte stream and thus can be transferred. The object conversion is done by the JVM using its default serialization mechanism.

If you don’t define serialVersionUID in your serilizable class, Java compiler will make one by creating a hash code using most of your class attributes and features. When an object gets serialized, this hash code is stamped on the object which is known as the SerialVersionUID of that object. This ID is required for the version control of an object. SerialVersionUID can be specified in the class file also. In case, this ID is not specified by you, then Java compiler will regenerate a SerialVersionUID based on updated class and it will not be possible for the already serialized class to recover when a class field is added or modified. Its recommended that you always declare a serialVersionUID in your Serializable classes.