Thursday, 24 February 2011

Clone, Cloneable, Deep and Shallow Clone


CLONE and CLONEABLE:
Clone is a protected method defined in Object class. To clone any class that class should must implement Cloneable interface which is a marker interface otherwise it will through CloneNotSupportedException. 
Cloneable is a marker interface so no method defined. Interesting thing is it does not support Generics probably because it was there before Generics or for backward compatibility.
Cloneable Vs Serialization:
Cloneable interface is used to make a clone of a object,every time create a new instance by new operator is costly in terms of JVM ,resource & performance. so we can create similar type of instance with the help of already been created instance by using clone()


Serialization is a process to convert your object into bitstream and send accross the network and deserialze at other end,process like Marshling. By default serialization dies Deep Copy.



SHALLOW COPY vs DEEP COPY:
Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure, not the elements. With a shallow copy, two collections now share the individual elements.
Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.

How to do SHALLOW COPY:
For shallow copy we can clone() method but make sure all field reference classes should also be Cloneable.

How to do DEEP COPY:

Solution 1: Use Copy Constructor

class DeepCloneableClass {
   //Define other constructor as usual

   //Copy Constructor for deep cloning
   public DeepCloneableClass(DeepCloneableClass from){
      this.field1  = from.getField1();
      ...
      ...
   }
}


Solution 2: Use Factory Pattern 

class DeepCloneableClass {

//Create factory method for deep cloning
    public static DeepCloneableClass fromInstance(DeepCloneableClass from){
        new DeepCloneableClass(from.getFeild1());
        ...
    }
}

Solution 3: Force by new Interface like DeepCloneable


interface DeepCloneable<T>{            
    //In implementaion create deep copy
    public T deepClone(T t);
}



Example Showing Difference Between Deep and Shallow Copy:
************************************************

package com.object;


class Person implements Cloneable {
// Lower-level object
private Car car;


private String name;


public Car getCar() {
return car;
}


public String getName() {
return name;
}


public void setName(String s) {
name = s;
}


public Person(String s, String t) {
name = s;
car = new Car(t);
}


public Object deepClone() {
// Deep copy
Person p = new Person(name, car.getName());
return p;
}


public Object shallowClone() {
// shallow copy
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}


class Car {


private String name;


public String getName() {
return name;
}


public void setName(String s) {
name = s;
}


public Car(String s) {
name = s;
}
}


public class DeepNShallowCopyTest {


public static void main(String[] args) {
// Original Object
Person p = new Person("Person-A", "Civic");
System.out.println("Original (orginal values): " + p.getName() + " - "
+ p.getCar().getName());


// Clone as a shallow copy
Person q = (Person) p.shallowClone();


System.out.println("Clone (before change): " + q.getName() + " - "
+ q.getCar().getName());


// change the primitive member
q.setName("Person-B");


// change the lower-level object
q.getCar().setName("Accord");


System.out.println("Clone (after change): " + q.getName() + " - "
+ q.getCar().getName());


System.out.println("Original (after clone is modified): " + p.getName()
+ " - " + p.getCar().getName());


System.out.println("********************************");


// Original Object
Person dp = new Person("Person-A", "Civic");
System.out.println("Original (orginal values): " + dp.getName() + " - "
+ dp.getCar().getName());


// Clone as a shallow copy
Person dq = (Person) dp.deepClone();


System.out.println("Clone (before change): " + dq.getName() + " - "
+ dq.getCar().getName());


// change the primitive member
dq.setName("Person-B");


// change the lower-level object
dq.getCar().setName("Accord");


System.out.println("Clone (after change): " + dq.getName() + " - "
+ dq.getCar().getName());


System.out.println("Original (after clone is modified): "
+ dp.getName() + " - " + dp.getCar().getName());


}
}

OUTOUT :

Original (orginal values): Person-A - Civic
Clone (before change): Person-A - Civic
Clone (after change): Person-B - Accord
Original (after clone is modified): Person-A - Accord
********************************
Original (orginal values): Person-A - Civic
Clone (before change): Person-A - Civic
Clone (after change): Person-B - Accord
Original (after clone is modified): Person-A - Civic

Thread Concepts

Difference between "green" threads and "native" threads?


Both green and native threads are mechanisms to support multithreaded execution of Java programs. Some JDK distributions (such as Blackdown's) include the option to run with either type of threading.
Native threads use the operating system's native ability to manage multi-threaded processes - in particular, they use the pthread library. When you run with native threads, the kernel schedules and manages the various threads that make up the process.
Green threads emulate multithreaded environments without relying on any native OS capabilities. They run code in user space that manages and schedules threads; Sun wrote green threads to enable Java to work in environments that do not have native thread support.
There are some important differences between using the two in a Linux environment:
  • Native threads can switch between threads pre-emptively, switching control from a running thread to a non-running thread at any time. Green threads only switch when control is explicitly given up by a thread (Thread.yield(), Object.wait(), etc.) or a thread performs a blocking operation (read(), etc.).
  • On multi-CPU machines, native threads can run more than one thread simultaneously by assigning different threads to different CPUs. Green threads run on only one CPU.
  • Native threads create the appearance that many Java processes are running: each thread takes up its own entry in the process table. One clue that these are all threads of the same process is that the memory size is identical for all the threads - they are all using the same memory.
    Unfortunately, this behavior limits the scalability of Java on Linux. The process table is not infinitely large, and processes can only create a limited number of threads before running out of system resources or hitting configured limits.

Atomic, Volatile, Transient

java.util.concurrent.atomic Description


A small toolkit of classes that support lock-free thread-safe programming on single variables. In essence, the classes in this package extend the notion ofvolatile values, fields, and array elements to those that also provide an atomic conditional update operation of the form:
  boolean compareAndSet(expectedValue, updateValue);
This method (which varies in argument types across different classes) atomically sets a variable to the updateValue if it currently holds theexpectedValue, reporting true on success. The classes in this package also contain methods to get and unconditionally set values, as well as a weaker conditional atomic update operation weakCompareAndSet. The weak version may be more efficient in the normal case, but differs in that any given invocation of weakCompareAndSet method may fail, even spuriously (that is, for no apparent reason). A false return means only that the operation may be retried if desired, relying on the guarantee that repeated invocation when the variable holds expectedValue and no other thread is also attempting to set the variable will eventually succeed. All primitive types are having atomic wrapper classes.
AtomicInteger
AtomicFloat
Atomic Double

VOLATILE:
-----------

Declaring a volatile Java variable means:
  • The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory";
  • Access to the variable acts as though it is enclosed in a synchronizedblock, synchronized on itself.
It can be used as a counter at class level or for implementing lock object etc.

TRANSIENT:
------------
The modifier transient can be applied to field members of a class to turn off serialization on these field members. Every field marked as transient will not be serialized. You use thetransient keyword to indicate to the Java virtual machine that the transient variable is not part of the persistent state of an object.
The transient modifier applies to variables only.
Like other variable modifiers in the Java system, you use transient in a class or instance variable declaration like this:
class TransientExample {
    transient int hobo;
    . . .
}



Q. Can transient variable may be static or final?
Surprisingly, the java compiler does not complaint if you declare a static member field astransient. However, there is no point in declaring a static member field as transient, sincetransient means: "do not serialize", and static fields would not be serialized anyway.
On the other hand, an instance member field declared as final could also be transient, but if so, you would face a problem a little bit difficult to solve: As the field is transient, its state would not be serialized, it implies that, when you deserialize the object you would have to initialize the field manually, however, as it is declared final, the compiler would complaint about it.

Saturday, 5 February 2011

ADVANCE THREAD

Java.util.concurrent package
Quick view on the important interfaces and classes bundled in this package.
Important Interfaces:
  1. ThreadFactory
  2. Executor
  3. ExecutorService
  4. ScheduledExecutorService
  5. Future<E>
  6. Callable<E>
  7. ScheduledFuture<E>
  8. BlockingQueue<V>
  9. ConcurrentMap<V>

Important Classes:
  1. Blocking queue implementation-
  2. ArrayBlockingQueue<v>
  3. LinkedBlockingQueue<V>
  4. PriorityBlockingQueue<v>
  5. SynchronousQueue<v>  
For high degree of concurrency-
  1. ConcurrentHashMap<k,v>
  2. ConcurrentLinkedQueue<v>
For iterator use to avoid ConcurrentModificationException exception-
  1. CopyOnWriteArrayList<>
  2. CopyOnWriteArraySet<>


Conditional Thread-Safety (Synchronized wrapper):
Java 1.2 adressed thread safety by introducing synchronized-collections wrappers, synchronizedMap and synchronizedList, are sometimes called Conditionally thread safe - all individual operations are thread-safe, but sequences of operations where the control flow depends on the results of previous operations may be subject to data races.
The conditional thread safety provided by synchronizedList and synchronizedMap present a hidden hazard -- developers assume that because these collections are synchronized, they are fully thread-safe, and they neglect to synchronize compound operations properly. The result is that while these programs appear to work under light load, under heavy load they may start throwing NullPointerException or ConcurrentModificationException.

Thread-Safety By immutability (CopyOnWriteArrayList and CopyOnWriteArraySet):
If you are using an ordinary ArrayList to store a list of listeners, as long as the list remains mutable and may be accessed by multiple threads, you must either lock the entire list during iteration or clone it before iteration, both of which have a significant cost. CopyOnWriteArrayList instead creates a fresh copy of the list whenever a mutative operation is performed, and its iterators are guaranteed to return the state of the list at the time the iterator was constructed and not throw a ConcurrentModificationException.
The CopyOnWriteArrayList class is intended as a replacement for the ArrayList in concurrent applications where traversals greatly outnumber insertions or removals. It helps to get all the thread-safety benefits of immutability without the need for locking.
ConcurrentHashMap:
ConcurrentHashMap is designed to optimize retrieval operations; in fact, successful get() operations usually succeed with no locking at all. Achieving thread-safety without locking is tricky and requires a deep understanding of the details of the Java Memory Model.
“ConcurrentHashMap achieves higher concurrency by slightly relaxing the promises it makes to callers. A retrieval operation will return the value inserted by the most recent completed insert operation, and may also return a value added by an insertion operation that is concurrently in progress (but in no case will it return a nonsense result). Iterators returned byConcurrentHashMap.iterator() will return each element once at most and will not ever throwConcurrentModificationException, but may or may not reflect insertions or removals that occurred since the iterator was constructed. No table-wide locking is needed (or even possible) to provide thread-safety when iterating the collection.ConcurrentHashMap may be used as a replacement for synchronizedMap or Hashtable in any application that does not rely on the ability to lock the entire table to prevent updates.”
Imp Note:
1.    Unlike HashMap and like HashTable, CocurrentHashMap does not allow null key, as it has been derived with intension to make compatible to HashMap and HashTable both.
2.    The related ConcurrentReaderHashMap class offers similar multiple-reader concurrency, but allows only a single active writer.
3.    This class supports a hard-wired preset concurrency level of 32. This allows a maximum of 32 put and/or remove operations to proceed concurrently. This level is an upper bound on concurrency
**Interesting : Why ConcurrentHashmap but no ConcurrentHashSet**
There is NOT any support for locking the entire table to prevent updates. This makes it impossible, for example, to add an element only if it is not already present, since another thread may be in the process of doing the same thing. If you need such capabilities, consider instead using the ConcurrentReaderHashMap class.
Blocking Queues and implementations:
A blocking queue is a queue that blocks when you try to dequeue from it and the queue is empty, or if you try to enqueue items to it and the queue is already full. A thread trying to dequeue from an empty queue is blocked until some other thread inserts an item into the queue. A thread trying to enqueue an item in a full queue is blocked until some other thread makes space in the queue, either by dequeuing one or more items or clearing the queue completely.  All BlockingQueue implementations are threadsafe.
  • A ConcurrentLinkedQueue is an appropriate choice when many threads will share access to a common collection. This queue does not permit null elements. This queue orders elements FIFO (first-in-first-out)
  • ArrayBlockingQueue is a classic "bounded buffer", in which a fixed-sized array holds elements inserted by producers and extracted by consumers. This class supports an optional fairness policy for ordering waiting producer and consumer threads. This queue orders elements FIFO (first-in-first-out). 
  • LinkedBlockingQueue typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.
  • PriorityBlockingQueue relying on natural ordering also does not permit insertion of non-comparable objects (doing so results in ClassCastException).
  • A synchronous queue does not have any internal capacity, not even a capacity of one. You cannot peek at a synchronous queue because an element is only present when you try to take it; you cannot add an element (using any method) unless another thread is trying to remove it; you cannot iterate as there is nothing to iterate

Difference between blocking queue implementations like:
ArrayBlockingQueue, LinkedBlockingQueue and ConcurrentLinkedQueue-

Basically the differences between them are performance characteristics and blocking behavior.
Taking the easiest first, ArrayBlockingQueue is a queue of a fixed size. So if you set the size at 10, and attempt to insert an 11th element, the insert statement will block until another thread removes an element. The fairness issue is what happens if multiple threads try to insert and remove at the same time (in other words during the period when the Queue was blocked). A fairness algorithm ensures that the first thread that asks is the first thread that gets. Otherwise, a given thread may wait longer than other threads, causing unpredictable behavior (sometimes one thread will just take several seconds because other threads that started later got processed first). The trade-off is that it takes overhead to manage the fairness, slowing down the throughput.

The most important difference between LinkedBlockingQueue and ConcurrentLinkedQueue is that if you request an element from a LinkedBlockingQueue and the queue is empty, your thread will wait until there is something there. A ConcurrentLinkedQueue will return right away with the behaviour of an empty queue.

Which one depends on if you need the blocking, Where you have many producers and one consumer, it sounds like it. On the other hand, where you have many consumers and only one producer, you may not need the blocking behaviour, and may be happy to just have the consumers check if the queue is empty and move on if it is.

Annexure Links:
http://www.ibm.com/developerworks/java/library/j-jtp07233.html

How Vector / HashTable are thread Safe?


java.util.Hashtable and java.util.Vector are two examples of JDK objects whose every method is synchronized. This imposes a large runtime cost on applications that iterate over these structures. When you are not using threads, prefer java.util.HashMap and java.util.ArrayList. Thread.sleep(5000) is supposed to sleep for 5 seconds. However, if somebody changes the system time, you may sleep for a very long time or no time at all. The OS records the wake up time in absolute form, not relative.


Monday, 31 January 2011

Differentiate JVM JRE JDK JIT


Java Virtual Machine (JVM) is an abstract computing machine. Java Runtime Environment (JRE) is an implementation of the JVM. Java Development Kit (JDK) contains JRE along with various development tools like Java libraries, Java source compilers, Java debuggers, bundling and deployment tools.
JVM becomes an instance of JRE at runtime of a java program. It is widely known as a runtime interpreter. The Java virtual machine (JVM) is the cornerstone on top of which the Java technology is built upon. It is the component of the Java technology responsible for its hardware and platform independence. JVM largely helps in the abstraction of inner implementation from the programmers who make use of libraries for their programmes from JDK.


Just-in-time Compiler (JIT)

JIT is the part of the Java Virtual Machine (JVM) that is used to speed up the execution time. JIT compiles parts of the byte code that have similar functionality at the same time, and hence reduces the amount of time needed for compilation. Here the term “compiler” refers to a translator from the instruction set of a Java virtual machine (JVM) to the instruction set of a specific CPU.


Diagram to show the relations between JVM JRE JDK
Diagram to show the relations between JVM JRE JDK

JVM Internals

Like a real computing machine, JVM has an instruction set and manipulates various memory areas at run time. Thus for different hardware platforms one has corresponding implementation of JVM available as vendor supplied JREs. It is common to implement a programming language using a virtual machine. Historicaly the best-known virtual machine may be the P-Code machine of UCSD Pascal.
A Java virtual machine instruction consists of an opcode specifying the operation to be performed, followed by zero or more operands embodying values to be operated upon. From the point of view of a compiler, the Java Virtual Machine (JVM)is just another processor with an instruction set, Java bytecode, for which code can be generated. Life cycle is as follows, source code to byte code to be interpreted by the JRE and gets converted to the platform specific executable ones.

Sun’s JVM

Sun’s implementations of the Java virtual machine (JVM) is itself called as JRE. Sun’s JRE is availabe as a separate application and also available as part of JDK. Sun’s Java Development Tool Kit (JDK) comes with utility tools for byte code compilation “javac”. Then execution of the byte codes through java programmes using “java” and many more utilities found in the binary directory of JDK. ‘java’ tools forks the JRE. Implementation of JVMs are also actively released by other companies besides Sun Micro Systems.

JVM for other languages

A JVM can also be used to implement programming languages other than Java. For example, Ada source code can be compiled to Java bytecode, which may then be executed by a Java virtual machine (JVM). That is, any language with functionality that can be expressed in terms of a valid class file can be hosted by the Java virtual machine (JVM). Attracted by a generally available, machine-independent platform, implementors of other languages are turning to the Java virtual machine (JVM) as a delivery vehicle for their languages. PHP with Quercus is such an example.


Various Flavors of Inner Classes


Static vs Non-Static Inner Classes:
There are main two differences:
  1. Non static inner class cannot have static data member and static member method
  2. A static inner class can have instances but they don’t have enclosing instances! Which a non-static inner class have.

In the case of creating instance, the instance of non so static inner class is created with the reference of object of outer class in which it is defined……this means it have inclosing instance …….But the instance of static inner class is created with the reference of Outer class, not with the reference of object of outer class…..this means it have not inclosing instance.


class A {

      static class B {
            static int i = 0;
      } // static-member class

      class C {
            // static int i =0;
      } // non-static member class
}

public class InnerClasses {
      public static void main(String st[]) {

            A obj1 = new A();
            A.C c = obj1.new C();// obj1 is enclosing instance
            A.B b = new A.B(); // No enclosing instance required

      }
}

Serialization vs Externalization


Serialization:

Primary purpose of java serialization is to write an object into a stream, so that it can be transported through a network and that object can be rebuilt again. When there are two different parties involved, you need a protocol to rebuild the exact same object again. Java serialization API just provides you that. Other ways you can leverage the feature of serialization is, you can use it to perform a deep copy.
The serialization mechanism has been added into the Java language for two reasons:
(1) the JavaBeans mechanism uses serialization for storing objects into flat file or when application runs in multiple JVM (JVM clustering for performance) it helps beans to move across JVMs over network
(2) remote method invocation (RMI) allows you to automatically use objects located at another host in the network just like any local objects.

Serialization is a Marker interface -Marker Interface is used by java runtime engine (JVM) to identify the class for special processing. Note, Serialization does not store Transient or any Static variable that associated with class rather than object.


1
2
3
4
5
Import java.io.serializable;
Class vinayworld implements Serializable {
Public String vinay_variable;
Private String vinay_add;
}
Other class would be
?
1
2
3
4
5
6
7
8
9
Public class vinayotherClass  {
Public static void main (String args[])
{
FileOutputStream fos=new FileOutputStream("vinay.txt");
    ObjectOutputStream oos=new ObjectOutputStream(fos);
Vinayworld vw = new vinayworld();
oos.writeobject(vw);
oos.flush();
oos.close();

Externalization:
Externalization is same as Sterilization except that WriteObject() and ReadObject() method are called by JVM during sterilization an desterilization of object. One thing you can do with Externalization is that you can store extra information into object like STATIC variables and transient variables or you can add more information if you have any business need. One good example is compressing and uncompressing of data to send it through network or converting one format to other like a BMP image to JPEG or GIF format.

Performance issue –
1. Further more if you are subclassing your externalizable class you will want to invoke your superclass’s implementation. So this causes overhead while you subclass your externalizable class.
2. methods in externalizable interface are public. So any malicious program can invoke which results into lossing the prior serialized state.


*******************************************************************
How to make singleton or immutable class serializable?
Ans: You can use writeReplace and readResolve methods to wrap inside a static proxy class.



private Object writeReplace() {} 
 

Object readResolve() {} 


For further details please read:
http://lingpipe-blog.com/2009/08/10/serializing-immutable-singletons-serialization-proxy/

*******************************************************************

Serialization Interview Questions

Q1) What is Serialization?
Ans) Serializable is a marker interface. When an object has to be transferred over a network ( typically through rmi or EJB) or persist the state of an object to a file, the object Class needs to implement Serializable interface. Implementing this interface will allow the object converted into bytestream and transfer over a network.
Q2) What is use of serialVersionUID?
Ans) During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names and types, and superclass. This class definition is stored as a part of the serialized object. This stored metadata enables the deserialization process to reconstitute the objects and map the stream data into the class attributes with the appropriate type
Everytime an object is serialized the java serialization mechanism automatically computes a hash value. ObjectStreamClass's computeSerialVersionUID() method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value.The serialVersionUID is also called suid.
So when the serilaize object is retrieved , the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the object. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If notInvalidClassException exception is thrown.

Changes to a serializable class can be compatible or incompatible. Following is the list of changes which are compatible:
  • Add fields
  • Change a field from static to non-static
  • Change a field from transient to non-transient
  • Add classes to the object tree
List of incompatible changes:
  • Delete fields
  • Change class hierarchy
  • Change non-static to static
  • Change non-transient to transient
  • Change type of a primitive field
So, if no suid is present , inspite of making compatible changes, jvm generates new suidthus resulting in an exception if prior release version object is used .
The only way to get rid of the exception is to recompile and deploy the application again.

If we explicitly metion the suid using the statement:

private final static long serialVersionUID = <integer value>


then if any of the metioned compatible changes are made the class need not to be recompiled. But for incompatible changes there is no other way than to compile again.
Q3) What is the need of Serialization?
Ans) The serialization is used :-
  • To send state of one or more object’s state over the network through a socket.
  • To save the state of an object in a file.
  • An object’s state needs to be manipulated as a stream of bytes.
Q4) Other than Serialization what are the different approach to make object Serializable?
Ans) Besides the Serializable interface, at least three alternate approaches can serialize Java objects:

1)For object serialization, instead of implementing the Serializable interface, a developer can implement the Externalizable interface, which extends Serializable. By implementing Externalizable, a developer is responsible for implementing the writeExternal() and readExternal() methods. As a result, a developer has sole control over reading and writing the serialized objects.
2)XML serialization is an often-used approach for data interchange. This approach lags runtime performance when compared with Java serialization, both in terms of the size of the object and the processing time. With a speedier XML parser, the performance gap with respect to the processing time narrows. Nonetheless, XML serialization provides a more malleable solution when faced with changes in the serializable object.
3)Finally, consider a "roll-your-own" serialization approach. You can write an object's content directly via either the ObjectOutputStream or the DataOutputStream. While this approach is more involved in its initial implementation, it offers the greatest flexibility and extensibility. In addition, this approach provides a performance advantage over Java serialization.
Q5) Do we need to implement any method of Serializable interface to make an object serializable?
Ans) No. Serializable is a Marker Interface. It does not have any methods.
Q6) What happens if the object to be serialized includes the references to other serializable objects?
Ans) If the object to be serialized includes the references to other objects whose class implements serializable then all those object’s state also will be saved as the part of the serialized state of the object in question. The whole object graph of the object to be serialized will be saved during serialization automatically provided all the objects included in the object’s graph are serializable.
Q7) What happens if an object is serializable but it includes a reference to a non-serializable object?
Ans- If you try to serialize an object of a class which implements serializable, but the object includes a reference to an non-serializable class then a ‘NotSerializableException’ will be thrown at runtime.

e.g.
public class NonSerial {
    //This is a non-serializable class
}
public class MyClass implements Serializable{
    private static final long serialVersionUID = 1L;
    private NonSerial nonSerial;
    MyClass(NonSerial nonSerial){
        this.nonSerial = nonSerial;
    }
    public static void main(String [] args) {
        NonSerial nonSer = new NonSerial();
        MyClass c = new MyClass(nonSer);
        try {
        FileOutputStream fs = new FileOutputStream("test1.ser");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(c);
        os.close();
        } catch (Exception e) { e.printStackTrace(); }
        try {
        FileInputStream fis = new FileInputStream("test1.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        c = (MyClass) ois.readObject();
        ois.close();
            } catch (Exception e) {
            e.printStackTrace();
          }
    }
}
On execution of above code following exception will be thrown  –
java.io.NotSerializableException: NonSerial
            at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java
Q8) Are the static variables saved as the part of serialization?
Ans) No. The static variables belong to the class and not to an object they are not the part of the state of the object so they are not saved as the part of serialized object.
Q9) What is a transient variable?
Ans) These variables are not included in the process of serialization and are not the part of the object’s serialized state.
Q10) What will be the value of transient variable after de-serialization?
Ans) It’s default value.
e.g. if the transient variable in question is an int, it’s value after deserialization will be zero.
public class TestTransientVal implements Serializable{

    private static final long serialVersionUID = -22L;
    private String name;
    transient private int age;
    TestTransientVal(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public static void main(String [] args) {
        TestTransientVal c = new TestTransientVal(1,"ONE");
        System.out.println("Before serialization: - " + c.name + " "+ c.age);
        try {
        FileOutputStream fs = new FileOutputStream("testTransients.ser");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(c);
        os.close();
        } catch (Exception e) { e.printStackTrace(); }


        try {
        FileInputStream fis = new FileInputStream("testTransients.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        c = (TestTransientVal) ois.readObject();
        ois.close();
        } catch (Exception e) { e.printStackTrace(); }
        System.out.println("After de-serialization:- " + c.name + " "+ c.age);
        }
}

Result of executing above piece of code –
Before serialization: - Value of non-transient variable ONE Value of transient variable 1
After de-serialization:- Value of non-transient variable ONE Value of transient variable 0
Explanation –
The transient variable is not saved as the part of the state of the serailized variable, it’s value after de-serialization is it’s default value.
Q11) Does the order in which the value of the transient variables and the state of the object using the defaultWriteObject() method are saved during serialization matter?
Ans) Yes.  As while restoring the object’s state the transient variables and the serializable variables that are stored must be restored in the same order in which they were saved.
Q12) How can one customize the Serialization process? or What is the purpose of implementing the writeObject() and readObject() method?
Ans) When you want to store the transient variables state as a part of the serialized object at the time of serialization the class must implement the following methods –
private void wrtiteObject(ObjectOutputStream outStream)
{
//code to save the transient variables state as a part of serialized object
}
private void readObject(ObjectInputStream inStream)
{
//code to read the transient variables state and assign it to the de-serialized object
}
e.g.
public class TestCustomizedSerialization implements Serializable{

    private static final long serialVersionUID =-22L;
    private String noOfSerVar;
    transient private int noOfTranVar;

    TestCustomizedSerialization(int noOfTranVar, String noOfSerVar) {
        this.noOfTranVar = noOfTranVar;
        this.noOfSerVar = noOfSerVar;
    }

    private void writeObject(ObjectOutputStream os) {

     try {
     os.defaultWriteObject();
     os.writeInt(noOfTranVar);
     } catch (Exception e) { e.printStackTrace(); }
     }

     private void readObject(ObjectInputStream is) {
     try {
     is.defaultReadObject();
     int noOfTransients = (is.readInt());
     } catch (Exception e) {
         e.printStackTrace(); }
     }

     public int getNoOfTranVar() {
        return noOfTranVar;
    }

}
The value of transient variable ‘noOfTranVar’ is saved as part of the serialized object manually by implementing writeObject() and restored by implementing readObject().
The normal serializable variables are saved and restored by calling defaultWriteObject() and defaultReadObject()respectively. These methods perform the normal serialization and de-sirialization process for the object to be saved or restored respectively.
Q13) If a class is serializable but its superclass in not , what will be the state of the instance variables inherited  from super class after deserialization?
Ans) The values of the instance variables inherited from superclass will be reset to the values they were given during the original construction of the object as the non-serializable super-class constructor will run.
E.g.
public class ParentNonSerializable {
    int noOfWheels;

    ParentNonSerializable(){
        this.noOfWheels = 4;
    }

}

public class ChildSerializable extends ParentNonSerializable implements Serializable {

    private static final long serialVersionUID = 1L;
    String color;

    ChildSerializable() {
        this.noOfWheels = 8;
        this.color = "blue";
    }
}

public class SubSerialSuperNotSerial {

    public static void main(String [] args) {

        ChildSerializable c = new ChildSerializable();
        System.out.println("Before : - " + c.noOfWheels + " "+ c.color);
        try {
        FileOutputStream fs = new FileOutputStream("superNotSerail.ser");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(c);
        os.close();
        } catch (Exception e) { e.printStackTrace(); }

        try {
        FileInputStream fis = new FileInputStream("superNotSerail.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        c = (ChildSerializable) ois.readObject();
        ois.close();
        } catch (Exception e) { e.printStackTrace(); }
        System.out.println("After :- " + c.noOfWheels + " "+ c.color);
        }
}
Result on executing above code –
Before : - 8 blue
After :- 4 blue
The instance variable ‘noOfWheels’ is inherited from superclass which is not serializable. Therefore while restoring it the non-serializable superclass constructor runs and its value is set to 8 and is not same as the value saved during serialization which is 4.
Q14) To serialize an array or a collection all the members of it must be serializable. True /False?
Ans) true.

Q 15) Can a singleton class used as serializable?
Ans: Yes

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class AppState implements Serializable
{
    private static AppState s_instance = null;

    public static synchronized AppState getInstance() {
        if (s_instance == null) {
            s_instance = new AppState();
        }
        return s_instance;
    }

    private AppState() {
        // initialize
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ois.defaultReadObject();
        synchronized (AppState.class) {
            if (s_instance == null) {
                // re-initialize if needed

                s_instance = this; // only if everything succeeds
            }
        }
    }

    // this function must not be called other than by the deserialization runtime
    private Object readResolve() throws ObjectStreamException {
        assert(s_instance != null);
        return s_instance;
    }

    public static void main(String[] args) throws Throwable {
        assert(getInstance() == getInstance());

            java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
            java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(baos);
            oos.writeObject(getInstance());
            oos.close();

            java.io.InputStream is = new java.io.ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(is);
            AppState s = (AppState)ois.readObject();
            assert(s == getInstance());
    }
}