Friday, November 3, 2017

Core Java Preparation_3 + Serialisation + Constructor + Design pattern

Constructor
Understood till now – Here are few more points about constructors
1.      Every class has a constructor whether it’s normal one or a abstract class.
2.      As stated above, constructor are not methods and they don’t have any return type.
3.      Constructor name and class name should be the same.
4.      Constructor can use any access specifier, they can be declared as private also. Private constructors are possible in java but there scope is within the class only.
5.      Like constructors method can also have name same as class name, but still they have return type, though which we can identify them that they are methods not constructors.
6.      If you don’t define any constructor within the class, compiler will do it for you and it will create a constructor for you.
7.      this() and super() should be the first statement in the constructor code. If you don’t mention them, compiler does it for you accordingly.
8.      Constructor overloading is possible but overriding is not possible. Which means we can have overloaded constructor in our class but we can’t override a constructor.
9.      Constructors can not be inherited.
10.  If Super class doesn’t have a no-arg(default) constructor then compiler would not define a default one in child class as it does in normal scenario.
11.  Interfaces do not have constructors.
12.  Abstract can have constructors and these will get invoked when a class, which implements interface, gets instantiated. (i.e. object creation of concrete class).
13.  A constructor can also invoke another constructor of the same class – By using this(). If you wanna invoke a arg-constructor then give something like: this(parameter list).

 

 Overriding in Java


No, you cannot override the constructor of the Super class. JVM will definitely call the super class constructor while creating the child class instance. So, whenever you create a subclass instance, it will invoke the base class constructor and then continue with the subclass constructor statements. Constructors are not Methods that can be overridden
No.
With inheritance you can get/obtain instance members only. Constructor is not a member of class. Jvm treats it specially to construct an object . You can check that by seeing byte code instructions.
By overriding, what you achieve ?? A constructor must construct the current object.

Why constructors can not be inherited in java?

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.
In simple words, a constructor cannot be inherited, since in subclasses it has a different name (the name of the subclass).
class A {
A();
}
 
class B extends A{
B();
}
You can do only:
B b=newB();// and not new A()
Methods, instead, are inherited with "the same name" and can be used.
As for the reason: It would not have much sense to inherit a constructor, since constructor of class A means creating an object of type A, and constructor of class B means creating an object of class B.
You can still use constructors from A inside B's implementation though:
class B extends A{
B(){super();}
}

Only members are inherited, and a constructor is not considered a member.
---------------------------------------------------------------------------------------------------------------------------
Java final

1) Java final variable

If you make any variable as final, you cannot change the value of final variable (It will be constant).
Example of final variable
There is a final variable speedlimit, we are going to change the value of this variable, but It can't be changed because final variable once assigned a value can never be changed.
1.      class Bike9{  
2.       final int speedlimit=90;//final variable  
3.       void run(){  
4.        speedlimit=400;  
5.       }  
6.       public static void main(String args[]){  
7.       Bike9 obj=new  Bike9();  
8.       obj.run();  
9.       }  
10.  }//end of class  
Output:Compile Time Error


2) Java final method

If you make any method as final, you cannot override it.
Example of final method
1.      class Bike{  
2.        final void run(){System.out.println("running");}  
3.      }  
4.           
5.      class Honda extends Bike{  
6.         void run(){System.out.println("running safely with 100kmph");}  
7.           
8.         public static void main(String args[]){  
9.         Honda honda= new Honda();  
10.     honda.run();  
11.     }  
12.  }  
Output:Compile Time Error


3) Java final class

If you make any class as final, you cannot extend it.
Example of final class
1.      final class Bike{}  
2.        
3.      class Honda1 extends Bike{  
4.        void run(){System.out.println("running safely with 100kmph");}  
5.          
6.        public static void main(String args[]){  
7.        Honda1 honda= new Honda();  
8.        honda.run();  
9.        }  
10.  }  
Output:Compile Time Error


Q) Is final method inherited?
Ans) Yes, final method is inherited but you cannot override it. For Example:
1.      class Bike{  
2.        final void run(){System.out.println("running...");}  
3.      }  
4.      class Honda2 extends Bike{  
5.         public static void main(String args[]){  
6.          new Honda2().run();  
7.         }  
8.      }  
Output:running...


Q) What is blank or uninitialized final variable?
A final variable that is not initialized at the time of declaration is known as blank final variable.
If you want to create a variable that is initialized at the time of creating object and once initialized may not be changed, it is useful. For example PAN CARD number of an employee.
It can be initialized only in constructor.
Example of blank final variable
1.      class Student{  
2.      int id;  
3.      String name;  
4.      final String PAN_CARD_NUMBER;  
5.      ...  
6.      }  
7.       
Q) Can we initialize blank final variable?
Yes, but only in constructor. For example:
1.      class Bike10{  
2.        final int speedlimit;//blank final variable  
3.          
4.        Bike10(){  
5.        speedlimit=70;  
6.        System.out.println(speedlimit);  
7.        }  
8.        
9.        public static void main(String args[]){  
10.      new Bike10();  
11.   }  
12.  }  
Output:70


static blank final variable
A static final variable that is not initialized at the time of declaration is known as static blank final variable. It can be initialized only in static block.
Example of static blank final variable
1.      class A{  
2.        static final int data;//static blank final variable  
3.        static{ data=50;}  
4.        public static void main(String args[]){  
5.          System.out.println(A.data);  
6.       }  
7.      }  


Q) What is final parameter?
If you declare any parameter as final, you cannot change the value of it.
1.      class Bike11{  
2.        int cube(final int n){  
3.         n=n+2;//can't be changed as n is final  
4.         n*n*n;  
5.        }  
6.        public static void main(String args[]){  
7.          Bike11 b=new Bike11();  
8.          b.cube(5);  
9.       }  
10.  }  
Output:Compile Time Error


Q) Can we declare a constructor final?
No, because constructor is never inherited.
`

JAVA Important Quetion

What is difference between final, finally and finalize method is asked to my friend in a Java interview with one of the US based Investment bank. Though it was just a telephonic round interview, he was asked couple of good questions e.g. how to avoid deadlock in Java, How get() method of HashMap works and one of the puzzle which is based on recursion. In short final keyword can be used along with variable, method and class and has different meaning for all of them. finally is another Java keyword which is used in Exception handling along with try, catch, throw and throws.finalize() is a special method in Java which is called by Garbage Collector before reclaiming GC eligible objects. In this Java interview questions article we will compare final vs finally vs finalize and highlight some important difference between final, finally and finalize method in Java.

1.2         final vs finally vs finalize in Java

As I said earlier final keyword can be used along with variable, method and Class in Java. If you make a variable final, you can not change it's value, it will act like a constant. final variables are initialized at the time of creation except in case of blank final variable which is initialized in Constructor. If you make a method final in Java, you can not override it in sub class . If you make a class final means it can not be sub classed. Making a class final automatically makes all its method final and this is sometime required due to security reason, This is one of the reason Why String is final in Java. In short final is not related at all with either finally or finalizekeyword. final keyword also help to write Immutable classes which are critical for designing thread-safe multi-threading system and reducing amount of synchronization. I would suggest to see What is final in Java for more information aboutfinal keyword.

Now let's see What is finally in Java? As I said finally is used for exception handling along with try and catch. As per Java programming language’s rule, for exception handling you at least need either catch or finally block. finallyblock has special advantage over catch that its guaranteed to be executed despite whether Exception is thrown or not, this makes it, an ideal place to close system resource e.g. InputStream or OutputStream, which is required to release scarce file descriptor. Closing streams, network connection, database connection in finally block is good coding practice in Java. By the way from Java 7 you can use try with resource block to close resource automatically. Since finally is guaranteed to be executed on most cases, it also gives birth to some tricky Java questions where finally doesn't execute e.g. returning value from finally block, calling System.exit from try block etc. finally block always execute, except in case of JVM dies i.e. calling System.exit() . Again finally is not related to final or finalize in any way.

Now let’s see What is finalize() method, finalize() is called by Garbage collection thread just before collecting eligible Objects. This is the last chance for object to perform any cleanup but since its not guaranteed that whether finalize() will be called, its bad practice to keep resource till finalize call. Though you can build a safety net on finalizeby double checking scarce resources. See 10 points on finalize method to know more about specific points of finalize().

So, final, finally and finalize all are different keyword, they are used for different purpose. only similarity between them is that they are a Java programming language keyword, other than that final, finalize and finally are completely different than each other.
------------------

final:
               final is a keyword. The variable decleared as final should be
               initialized only once and cannot be changed. Java classes
               declared as final cannot be extended. Methods declared as final
               cannot be overridden.
               
finally:
               finally is a block. The finally block always executes when the
               try block exits. This ensures that the finally block is executed
               even if an unexpected exception occurs. But finally is useful for
               more than just exception handling - it allows the programmer to
               avoid having cleanup code accidentally bypassed by a return,
               continue, or break. Putting cleanup code in a finally block is
               always a good practice, even when no exceptions are anticipated.
               
finalize:
               finalize is a method. Before an object is garbage collected, the
               runtime system calls its finalize() method. You can write system
               resources release code in finalize() method before getting garbage
               collected.


2           Exception Handling Examples

  • An exception is an event, which occurs during the execution of a program, that interrupts the normal flow of the program. It is an error thrown by a class or method reporting an error in code.
  • The 'Throwable' class is the superclass of all errors and exceptions in the Java language
  • Exceptions are broadly classified as 'checked exceptions' and 'unchecked exceptions'. All RuntimeExceptions and Errors are unchecked exceptions. Rest of the exceptions are called checked exceptions. Checked exceptions should be handled in the code to avoid compile time errors.
  • Exceptions can be handled by using 'try-catch' block. Try block contains the code which is under observation for exceptions. The catch block contains the remedy for the exception. If any exception occurs in the try block then the control jumps to catch block.
  • If a method doesn't handle the exception, then it is mandatory to specify the exception type in the method signature using 'throws' clause.
  • We can explicitly throw an exception using 'throw' clause.
-------------------------------------------------------------------------------------------------------------------------------
Design Pattern


Design Pattern Introduction

A design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into source or machine code. It is a description or template for how to solve a problem that can be used in many different situations. Patterns are formalized best practices that the programmer must implement in the application. Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved. Patterns that imply object-orientation or more generally mutable state, are not as applicable in functional programming languages.
The types of design patterns are Creational, Structural, and Behavioral design patterns.
Creational Design Pattern
Creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation. Types of creational design patterns are:
  1. Singleton Pattern
  2. Factory Pattern
  3. Abstract Factory Pattern
  4. Builder Pattern
  5. Prototype Pattern
Structural Design Pattern
Structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities.
  1. Adapter Pattern
  2. Composite Pattern
  3. Proxy Pattern
  4. Flyweight Pattern
  5. Facade Pattern
  6. Bridge Pattern
  7. Decorator Pattern

Structural design patterns are concerned with how classes and objects can be composed, to form larger structures.

The structural design patterns simplifies the structure by identifying the relationships.

These patterns focus on, how the classes inherit from each other and how they are composed from other classes.


Behavioral Design Pattern
Behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.
  1. Template Method Pattern
  2. Mediator Pattern
  3. Chain of Responsibility Pattern
  4. Observer Pattern
  5. Strategy Pattern
  6. Command Pattern
  7. State Pattern
  8. Visitor Pattern
  9. Iterator Pattern
  10. Memento Pattern

Java Singleton Design Pattern Best Practices with Examples
Singleton is one of the Gangs of Four Design patterns and comes in the Creational Design Pattern category. From the definition, it seems to be a very simple design pattern but when it comes to implementation, it comes with a lot of implementation concerns. The implementation of Singleton pattern has always been a controversial topic among developers. Here we will learn about Singleton design pattern principles, different ways to implement Singleton and some of the best practices for it’s usage.
Singleton Pattern
Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the instance of the class. Singleton pattern is used for logging, drivers objects, caching and thread pool.
Singleton design pattern is also used in other design patterns like Abstract Factory, Builder, Prototype, Facade etc. Singleton design pattern is used in core java classes also, for example java.lang.Runtime, java.awt.Desktop.
Java Singleton Pattern
To implement Singleton pattern, we have different approaches but all of them have following common concepts.
  • Private constructor to restrict instantiation of the class from other classes.
  • Private static variable of the same class that is the only instance of the class.
  • Public static method that returns the instance of the class, this is the global access point for outer world to get the instance of the singleton class.
In further sections, we will learn different approaches of Singleton pattern implementation and design concerns with the implementation.
  1. Eager initialization
  2. Static block initialization
  3. Lazy Initialization
  4. Thread Safe Singleton
  5. Bill Pugh Singleton Implementation
  6. Using Reflection to destroy Singleton Pattern
  7. Enum Singleton
  8. Serialization and Singleton
Eager initialization
In eager initialization, the instance of Singleton Class is created at the time of class loading, this is the easiest method to create a singleton class but it has a drawback that instance is created even though client application might not be using it.
Here is the implementation of static initialization singleton class.
EagerInitializedSingleton.java
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.journaldev.singleton;

public class EagerInitializedSingleton {
     
    private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();
     
    //private constructor to avoid client applications to use constructor
    private EagerInitializedSingleton(){}

    public static EagerInitializedSingleton getInstance(){
        return instance;
    }
}
If your singleton class is not using a lot of resources, this is the approach to use. But in most of the scenarios, Singleton classes are created for resources such as File System, Database connections etc and we should avoid the instantiation until unless client calls the getInstance method. Also this method doesn’t provide any options for exception handling.
Static block initialization
Static block initialization implementation is similar to eager initialization, except that instance of class is created in the static block that provides option for exception handling.


StaticBlockSingleton.java
1
package com.journaldev.singleton;

public class StaticBlockSingleton {

    private static StaticBlockSingleton instance;
     
    private StaticBlockSingleton(){}
     
    //static block initialization for exception handling
    static{
        try{
            instance = new StaticBlockSingleton();
        }catch(Exception e){
            throw new RuntimeException("Exception occured in creating singleton instance");
        }
    }
     
    public static StaticBlockSingleton getInstance(){
        return instance;
    }
}

Both eager initialization and static block initialization creates the instance even before it’s being used and that is not the best practice to use. So in further sections, we will learn how to create Singleton class that supports lazy initialization.
Lazy Initialization
Lazy initialization method to implement Singleton pattern creates the instance in the global access method. Here is the sample code for creating Singleton class with this approach.
LazyInitializedSingleton.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.journaldev.singleton;

public class LazyInitializedSingleton {

    private static LazyInitializedSingleton instance;
     
    private LazyInitializedSingleton(){}
     
    public static LazyInitializedSingleton getInstance(){
        if(instance == null){
            instance = new LazyInitializedSingleton();
        }
        return instance;
    }
}
The above implementation works fine incase of single threaded environment but when it comes to multithreaded systems, it can cause issues if multiple threads are inside the if loop at the same time. It will destroy the singleton pattern and both threads will get the different instances of singleton class. In next section, we will see different ways to create a thread-safe singleton class.
Thread Safe Singleton
The easier way to create a thread-safe singleton class is to make the global access method synchronized, so that only one thread can execute this method at a time. General implementation of this approach is like the below class.



ThreadSafeSingleton.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.journaldev.singleton;

public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;
     
    private ThreadSafeSingleton(){}
     
    public static synchronized ThreadSafeSingleton getInstance(){
        if(instance == null){
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }
}
Above implementation works fine and provides thread-safety but it reduces the performance because of cost associated with the synchronized method, although we need it only for the first few threads who might create the separate instances (Read: Java Synchronization). To avoid this extra overhead every time, double checked locking principle is used. In this approach, the synchronized block is used inside the if condition with an additional check to ensure that only one instance of singleton class is created.
Below code snippet provides the double checked locking implementation.
1
2
3
4
5
6
7
8
9
10
public static ThreadSafeSingletongetInstanceUsingDoubleLocking(){
    if(instance == null){
        synchronized (ThreadSafeSingleton.class) {
            if(instance == null){
                instance = new ThreadSafeSingleton();
            }
        }
    }
    return instance;
}


Bill Pugh Singleton Implementation
Prior to Java 5, java memory model had a lot of issues and above approaches used to fail in certain scenarios where too many threads try to get the instance of the Singleton class simultaneously. So Bill Pugh came up with a different approach to create the Singleton class using ainner static helper class. The Bill Pugh Singleton implementation goes like this;
BillPughSingleton.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.journaldev.singleton;

public class BillPughSingleton {

private BillPughSingleton(){}

private static class SingletonHelper{
private static final BillPughSingleton INSTANCE = new BillPughSingleton();
}

public static BillPughSingletongetInstance(){
return SingletonHelper.INSTANCE;
}
}
Notice the private inner static class that contains the instance of the singleton class. When the singleton class is loaded, SingletonHelper class is not loaded into memory and only when someone calls the getInstance method, this class gets loaded and creates the Singleton class instance.
This is the most widely used approach for Singleton class as it doesn’t require synchronization. I am using this approach in many of my projects and it’s easy to understand and implement also.
Using Reflection to destroy Singleton Pattern
Reflection can be used to destroy all the above singleton implementation approaches. Let’s see this with an example class.
ReflectionSingletonTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.journaldev.singleton;


import java.lang.reflect.Constructor;


public class ReflectionSingletonTest {

    public static void main(String[] args) {
        EagerInitializedSingletoninstanceOne = EagerInitializedSingleton.getInstance();
        EagerInitializedSingletoninstanceTwo = null;
        try {
            Constructor[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                //Below code will destroy the singleton pattern
                constructor.setAccessible(true);
                instanceTwo = (EagerInitializedSingleton) constructor.newInstance();
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(instanceOne.hashCode());
        System.out.println(instanceTwo.hashCode());
    }

}
When you run the above test class, you will notice that hashCode of both the instances are not same that destroys the singleton pattern. Reflection is very powerful and used in a lot of frameworks like Spring and Hibernate, do check out Java Reflection Tutorial.
Enum Singleton
To overcome this situation with Reflection, Joshua Bloch suggests the use of Enum to implement Singleton design pattern as Java ensures that any enum value is instantiated only once in a Java program. Since Java Enum values are globally accessible, so is the singleton. The drawback is that the enum type is somewhat inflexible; for example, it does not allow lazy initialization.
EnumSingleton.java
1
2
3
4
5
6
7
8
9
10
package com.journaldev.singleton;

public enumEnumSingleton {

    INSTANCE;
     
    public static void doSomething(){
        //do something
    }
}
Read: Java Enum
Serialization and Singleton
Sometimes in distributed systems, we need to implement Serializable interface in Singleton class so that we can store it’s state in file system and retrieve it at later point of time. Here is a small singleton class that implements Serializable interface also.

SerializedSingleton.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.journaldev.singleton;

import java.io.Serializable;

public class SerializedSingleton implements Serializable{

    private static final long serialVersionUID = -7604766932017737115L;

    private SerializedSingleton(){}
     
    private static class SingletonHelper{
        private static final SerializedSingleton instance = new SerializedSingleton();
    }
     
    public static SerializedSingletongetInstance(){
        return SingletonHelper.instance;
    }
     
}
The problem with above serialized singleton class is that whenever we deserialize it, it will create a new instance of the class. Let’s see it with a simple program.
SingletonSerializedTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.journaldev.singleton;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class SingletonSerializedTest {

    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        SerializedSingletoninstanceOne = SerializedSingleton.getInstance();
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
                "filename.ser"));
        out.writeObject(instanceOne);
        out.close();
         
        //deserailize from file to object
        ObjectInput in = new ObjectInputStream(new FileInputStream(
                "filename.ser"));
        SerializedSingletoninstanceTwo = (SerializedSingleton) in.readObject();
        in.close();
         
        System.out.println("instanceOnehashCode="+instanceOne.hashCode());
        System.out.println("instanceTwohashCode="+instanceTwo.hashCode());
         
    }

}
Output of the above program is;
1
2
instanceOnehashCode=2011117821
instanceTwohashCode=109647522
So it destroys the singleton pattern, to overcome this scenario all we need to do it provide the implementation of readResolve() method.
1
2
3
protected Object readResolve() {
    return getInstance();
}
After this you will notice that hashCode of both the instances are same in test program.
I hope this article helps you in grasping fine details of Singleton design pattern, do let me know through your thoughts and comments.
Related Posts:

Design Pattern - Factory Pattern


Factory pattern is one of the most used design patterns in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

Implementation

We're going to create a Shape interface and concrete classes implementing the Shape interface. A factory class ShapeFactory is defined as a next step.
FactoryPatternDemo, our demo class will use ShapeFactory to get a Shapeobject. It will pass information (CIRCLE / RECTANGLE / SQUARE) to ShapeFactory to get the type of object it needs.

Step 1

Create an interface.
Shape.java
publicinterfaceShape{
void draw();
}

Step 2

Create concrete classes implementing the same interface.
Rectangle.java
publicclassRectangleimplementsShape{
 
@Override
publicvoid draw(){
System.out.println("Inside Rectangle::draw() method.");
}
}
Square.java
publicclassSquareimplementsShape{
 
@Override
publicvoid draw(){
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
publicclassCircleimplementsShape{
 
@Override
publicvoid draw(){
System.out.println("Inside Circle::draw() method.");
}
}

Step 3

Create a Factory to generate object of concrete class based on given information.
ShapeFactory.java
publicclassShapeFactory{
               
//use getShape method to get object of type shape 
publicShape getShape(String shapeType){
if(shapeType ==null){
returnnull;
}                             
if(shapeType.equalsIgnoreCase("CIRCLE")){
returnnewCircle();
 
}elseif(shapeType.equalsIgnoreCase("RECTANGLE")){
returnnewRectangle();
 
}elseif(shapeType.equalsIgnoreCase("SQUARE")){
returnnewSquare();
}
 
returnnull;
}
}

Step 4

Use the Factory to get object of concrete class by passing an information such as type.
FactoryPatternDemo.java
publicclassFactoryPatternDemo{
 
publicstaticvoid main(String[] args){
ShapeFactory shapeFactory =newShapeFactory();
 
//get an object of Circle and call its draw method.
Shape shape1 = shapeFactory.getShape("CIRCLE");
 
//call draw method of Circle
      shape1.draw();
 
//get an object of Rectangle and call its draw method.
Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
//call draw method of Rectangle
      shape2.draw();
 
//get an object of Square and call its draw method.
Shape shape3 = shapeFactory.getShape("SQUARE");
 
//call draw method of circle
      shape3.draw();
}
}

Step 5

Verify the output.
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.




Abstract Factory Pattern 

 

Abstract Factory Pattern says that just define an interface or abstract class for creating families of related (or dependent) objects but without specifying their concrete sub-classes. 

 

Abstract Factory lets a class returns a factory of classes. So, this is the reason that Abstract Factory Pattern is one level higher than the Factory Pattern. 

An Abstract Factory Pattern is also known as Kit. 

 

Advantage of Abstract Factory Pattern 

  • Abstract Factory Pattern isolates the client code from concrete (implementation) classes. 
  • It eases the exchanging of object families. 
  • It promotes consistency among objects. 

Usage of Abstract Factory Pattern 

  • When the system needs to be independent of how its object are created, composed, and represented. 
  • When the family of related objects has to be used together, then this constraint needs to be enforced. 
  • When you want to provide a library of objects that does not show implementations and only reveals interfaces. 
  • When the system needs to be configured with one of a multiple family of objects. 

Abstract Factory patterns work around a super-factory which creates other factories. This factory is also called as factory of factories. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

In Abstract Factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern.










Abstract Factory patterns work around a super-factory which creates other factories. This factory is also called as factory of factories. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

In Abstract Factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern.

Implementation

We are going to create a Shape interface and a concrete class implementing it. We create an abstract factory class AbstractFactory as next step. Factory class ShapeFactory is defined, which extends AbstractFactory. A factory creator/generator class FactoryProducer is created.

AbstractFactoryPatternDemo, our demo class uses FactoryProducer to get a AbstractFactory object. It will pass information (CIRCLE / RECTANGLE / SQUARE for Shape) to AbstractFactory to get the type of object it needs.

Abstract Factory Pattern UML Diagram


=====================================================


------------------------------------------------------------------------------------------------------------
 Serialization















Java provides a mechanism, called object serialization where an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory.
Most impressive is that the entire process is JVM independent, meaning an object can be serialized on one platform and deserialized on an entirely different platform.
Classes ObjectInputStream and ObjectOutputStream are high-level streams that contain the methods for serializing and deserializing an object.
Serialization:
import java.io.*;

public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "PhokkaKuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
      {
FileOutputStream fileOut =
newFileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOExceptioni)
{
i.printStackTrace();
      }
   }
}

1.1         Deserializing an Object:

import java.io.*;
publicclassDeserializeDemo
{
publicstaticvoid main(String[]args)
{
Employee e =null;
try
{
FileInputStream    fileIn=new FileInputStream("/tmp/employee.ser");
ObjectInputStream     in=newObjectInputStream(fileIn);
 e =(Employee)in.readObject();
in.close();
fileIn.close();
}catch(IOExceptioni)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: "+ e.name);
System.out.println("Address: "+e.address);
System.out.println("SSN: "+e.SSN);
System.out.println("Number: "+e.number);
}
}
This would produce the following result:
DeserializedEmployee...
Name:ReyanAli
Address:PhokkaKuan,AmbehtaPeer
SSN:0
Number:101
 
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 to 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 mention the sUid using the statement:
private final static long serialVersionUID =<integer value>
then if any of the mentioned 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:
  • 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.
  • 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.
  • 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 references to the other objects, 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.

public class NonSerial{
//This is a non-serializable  class
}
public class MyClass implements Serializable{
private static final long serialVersionUID = 1L;
private NonSerial nonSerial;
MyClass(NonSerialnonSerial){
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 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("testTransient.ser");
ObjectOutputStream os=new  ObjectOutputStream(fs);
os.writeObject(c);
os.close();
}catch(Exception e){e.printStackTrace();}
try{
FileInputStreamf is=new  FileInputStream("testTransient.ser");
ObjectInputStreamo is=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, 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(ObjectOutputStreamoutStream){
//code to save the transient variables state
//as a part of serialized  object
}
private  void   readObject(ObjectInputStreaminStream){
//code to read the transient variables state
//and assign it to the  de-serialized object
}

public  class   TestCustomizedSerialization  implements Serializable{
private  static  final   long serialVersionUID =-22L;
private String  noOfSerVar;
transient   private  int  noOfTranVar;
TestCustomizedSerialization(intnoOfTranVar, String  noOfSerVar){
this.noOfTranVar=noOfTranVar;
this.noOfSerVar=noOfSerVar;
}
private  void   writeObject(ObjectOutputStreamos){
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();}
}
publicintgetNoOfTranVar(){
returnnoOfTranVar;
}
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-serialization 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.
publicclassChildSerializableextendsParentNonSerializableimplementsSerializable{
privatestaticfinallong serialVersionUID = 1L;
  String color;
ChildSerializable(){
this.noOfWheels= 8;
this.color="blue";
}
}

publicclassSubSerialSuperNotSerial{
publicstaticvoidmain(String []args){
ChildSerializable c =newChildSerializable();
System.out.println("Before : -  "+c.noOfWheels+" "+c.color);
try{
FileOutputStream fs =newFileOutputStream("superNotSerail.ser");
ObjectOutputStreamos=newObjectOutputStream(fs);
os.writeObject(c);
os.close();
}catch(Exception e){e.printStackTrace();}
try{
FileInputStreamfis=newFileInputStream("superNotSerail.ser");
ObjectInputStreamois=newObjectInputStream(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.
------------------------------------------------------------------------------------

SerialVersionUID 




2       Externalization in Java


What is externalization?
What is Externalizable?
Why do we use serializable interface in Java?
What is the use of serialization and Deserialization in Java?
What is serialization in Java?
What does it mean to serialize data?
What does it mean to serialize an object?
What is meant by transient in Java?
What is the use of XML serialization?
What is Deserialization C#?
What is deserialize XML?
What is an XML schema?
What does it mean to deserialize?
What is meant by delegates in C#?
What is serialization in JSON?
What is a serialized show?
What is serialization in the pharma world?
What is a serialization?
What do mean by track and trace in pharma?
What is electronic pedigree?

 

Externalizable



Serialization and Externalization in Java

Serializable vs Externalization in Java

here are some more differences between Serializable and Externalizable interface in Java:\
1. In case of Serializable, default serialization process is used. while in case of Externalizable custom Serialization process is used which is implemented by application.
2. JVM gives call back to readExternel() and writeExternal() of java.io.Externalizalbe interface for restoring and writing objects into persistence.
3. Externalizable interface provides complete control of serialization process to application.
4. readExternal() and writeExternal() supersede any specific implementation of writeObject and readObject methods.
Though Externalizable provides complete control, it also presents challenges to serialize super type state and take care of default values in case of transient variable and static variables in Java. If used correctly Externalizable interface can improve performance of serialization process.
That’s all on Difference between Externalizable and Serializable interface in Java. This is always asked when Java interview take turn towards Serialization after Multi-Threading questions and Collections Interview questions. Only problem with Serialization is that not many programmer use it and that’s why it look little difficult otherwise once you familiar with Serialization process and rules of Serialization, interview questions can be more easily handled.

Before going into what externalization is, you need to have some knowledge on what serialization is because externalization is nothing but serialization but an alternative for it and Externalizable interface extends Serializable interface. Check Serialization article for information on serialization. Just as an overview, Serialization is the process of converting an object's state (including its references) to a sequence of bytes, as well as the process of rebuilding those bytes into a live object at some future time. Serialization can be achieved by an object by implementing Serializable interface or Externalizable interface.
Well, when serialization by implementing Serializable interface is serving your purpose, why should you go for externalization?
Good question! Serializing by implementing Serializable interface has some issues. Lets see one by one what they are.
·         Serialization is a recursive algorithm. What I mean to say here is, apart from the fields that are required, starting from a single object, until all the objects that can be reached from that object by following instance variables, are also serialized. This includes the super class of the object until it reaches the "Object" class and the same way the super class of the instance variables until it reaches the "Object" class of those variables. Basically all the objects that it can read. This leads to lot of overheads. Say for example, you need only car type and licence number but using serialization, you cannot stop there. All the information that includes description of car, its parts, blah blah will be serialized. Obviously this slows down the performance.

·         Both serializing and deserializing require the serialization mechanism to discover information about the instance it is serializing. Using the default serialization mechanism, will use reflection to discover all the field values. Also the information about class description is added to the stream which includes the descption of all the serializable superclasses, the description of the class and the instance data associated with the specific instance of the class. Lots of data and metadata and again performance issue.

·         You know that serialization needs serialVersionUID, a unique Id to identify the information persisted. If you dont explicitly set a serialiVersionUID, serialization will compute the serialiVersionUID by going through all the fields and methods. So based on the size of the class, again serialization mechanism takes respective amount of time to calculate the value. A third performance issue.

Above three points confirm serialization has performance issues. Apart from performance issues,
·         When an object that implements Serializable interface, is serialized or de-serialized, no constructor of the object is called and hence any initialization which is done in the constructor cannot be done. Although there is an alternative of writing all initialization logic in a separate method and call it in constructor and readObject methods so that when an object is created or deserialized, the initialization process can happen but it definitely is a messy approach.
The solution for all the above issues is Externalization. Cool. Here enters the actual topic.
So what is externalization?
Externalization is nothing but serialization but by implementing Externalizable interface to persist and restore the object. To externalize your object, you need to implement Externalizable interface that extends Serializable interface. Here only the identity of the class is written in the serialization stream and it is the responsibility of the class to save and restore the contents of its instances which means you will have complete control of what to serialize and what not to serialize. But with serialization the identity of all the classes, its superclasses, instance variables and then the contents for these items is written to the serialization stream. But to externalize an object, you need a default public constructor.
Unlike Serializable interface, Externalizable interface is not a marker interface and it provides two methods - writeExternal and readExternal. These methods are implemented by the class to give the class a complete control over the format and contents of the stream for an object and its supertypes. These methods must explicitly coordinate with the supertype to save its state. These methods supersede customized implementations of writeObject and readObject methods.
How serialization happens? JVM first checks for the Externalizable interface and if object supports Externalizable interface, then serializes the object using writeExternal method. If the object does not support Externalizable but implement Serializable, then the object is saved using ObjectOutputStream. Now when an Externalizable object is reconstructed, an instance is created first using the public no-arg constructor, then the readExternal method is called. Again if the object does not support Externalizable, then Serializable objects are restored by reading them from an ObjectInputStream.
Lets see a simple example.
 
import java.io.*;
 
public class Car implements Externalizable {
    String name;
    int year;
    /*
     * mandatory public no-arg constructor
     */
    public Car() { super(); }
    Car(String n, int y) {
               name = n;
               year = y;
    }
    /** 
     * Mandatory writeExernal method. 
     */
    public void writeExternal(ObjectOutput out) throws IOException  {
               out.writeObject(name);
               out.writeInt(year);
    }
    /** 
     * Mandatory readExternal method. 
     */
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
               name = (String) in.readObject();
               year = in.readInt();
    }
    /** 
     * Prints out the fields. used for testing!
     */
    public String toString() {
        return("Name: " + name + "\n" + "Year: " + year);
    }
}
 
 
import java.io.*;
public class ExternExample {
    public static void main(String args[]) {
               // create a Car object 
               Car car = new Car("Mitsubishi", 2009);
               Car newCar = null;
               //serialize the car
               try {
                   FileOutputStream fo = new FileOutputStream("tmp");
                   ObjectOutputStream so = new ObjectOutputStream(fo);
                   so.writeObject(car);
                   so.flush();
               } catch (Exception e) {
                   System.out.println(e);
                   System.exit(1);
               }
 
               // de-serialize the Car
               try {
                   FileInputStream fi = new FileInputStream("tmp");
                   ObjectInputStream si = new ObjectInputStream(fi);     
                   newCar = (Car) si.readObject();
               }
               catch (Exception e) {
                   System.out.println(e);
                   System.exit(1);
               }
 
               /* 
                * Print out the original and new car information
                */
               System.out.println("The original car is ");
               System.out.println(car);
               System.out.println("The new car is ");
        System.out.println(newCar);
    }
}
In this example, class Car implements Externalizable interface which means that car object is ready for serialization. This class have two public methods - "writeExternal" and "readExternal". Unlike Serializable interface which will serialize all the variables in the object with just by implementing the interface, here you have to explicitly mention what fields or variables you want to serialize and the same is done in "writeExternal" and "readExternal" methods. So in the "ExternExample" class, when you write the "Car" object to the OutputStream, the "writeExternal" method is called and the data is persisted. The same applies to "readExternal" method in the Car object i.e., when you read the "Car" object from the ObjectInputStream, "readExternal" method is called.
What will happen when an externalizable class extends a non externalizable super class?
Then in this case, you need to persist the super class fields also in the sub class that implements Externalizable interface. Look at this example.
/**
 * The superclass does not implement externalizable
 */
class Automobile  {
    /*
     * Instead of making thse members private and adding setter
     * and getter methods, I am just giving default access specifier.
     * You can make them private members and add setters and getters.
     */
    String regNo;
    String mileage;
    /* 
     * A public no-arg constructor 
     */
    public Automobile() {}
    Automobile(String rn, String m) {
               regNo = rn;
               mileage = m;
    }
}
public class Car extends Automobile implements Externalizable {
    String name;
    int year;
    /*
     * mandatory public no-arg constructor
     */
    public Car() { super(); }
    Car(String n, int y) {
               name = n;
               year = y;
    }
    /** 
     * Mandatory writeExernal method. 
     */
    public void writeExternal(ObjectOutput out) throws IOException  {
               /* 
                * Since the superclass does not implement the Serializable interface
                * we explicitly do the saving.
                */
               out.writeObject(regNo);
               out.writeObject(mileage);
 
               //Now the subclass fields
               out.writeObject(name);
               out.writeInt(year);
    }
    /** 
     * Mandatory readExternal method. 
     */
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
               /* 
                * Since the superclass does not implement the Serializable interface
                * we explicitly do the restoring
                */
               regNo = (String) in.readObject();
               mileage = (String) in.readObject();
               
               //Now the subclass fields
               name = (String) in.readObject();
               year = in.readInt();
    }
 
    /** 
     * Prints out the fields. used for testing!
     */
    public String toString() {
        return("Reg No: " + regNo + "\n" + "Mileage: " + mileage +
                                      "Name: " + name + "\n" + "Year: " + year );
    }
}
Here the Automobile class does not implement Externalizable interface. So to persist the fields in the automobile class the writeExternal and readExternal methods of Car class are modified to save/restore the super class fields first and then the sub class fields.
Sounds good! What if the super class implements the Externalizable interface?
Well, in this case the super class will also have the readExternal and writeExternal methods as in Car class and will persist the respective fields in these methods. 
import java.io.*;
/**
 * The superclass implements externalizable
 */
class Automobile implements Externalizable {
    /*
     * Instead of making thse members private and adding setter
     * and getter methods, I am just giving default access specifier.
     * You can make them private members and add setters and getters.
     */
    String regNo;
    String mileage;
    /* 
     * A public no-arg constructor 
     */
    public Automobile() {}
    Automobile(String rn, String m) {
               regNo = rn;
               mileage = m;
    }
 
    public void writeExternal(ObjectOutput out) throws IOException {
               out.writeObject(regNo);
               out.writeObject(mileage);
    }
 
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        regNo = (String)in.readObject();
        mileage = (String)in.readObject();
    }
 
}
 
public class Car extends Automobile implements Externalizable {
 
    String name;
    int year;
 
    /*
     * mandatory public no-arg constructor
     */
    public Car() { super(); }
 
    Car(String n, int y) {
               name = n;
               year = y;
    }
 
    /** 
     * Mandatory writeExernal method. 
     */
    public void writeExternal(ObjectOutput out) throws IOException  {
               // first we call the writeExternal of the superclass as to write
               // all the superclass data fields
               super.writeExternal(out);
 
               //Now the subclass fields
               out.writeObject(name);
               out.writeInt(year);
    }
 
    /** 
     * Mandatory readExternal method. 
     */
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
               // first call the superclass external method
               super.readExternal(in);
 
               //Now the subclass fields
               name = (String) in.readObject();
               year = in.readInt();
    }
 
    /** 
     * Prints out the fields. used for testing!
     */
    public String toString() {
        return("Reg No: " + regNo + "\n" + "Mileage: " + mileage +
                                      "Name: " + name + "\n" + "Year: " + year );
    }
}
 
In this example since the Automobile class stores and restores its fields in its own writeExternal and readExternal methods, you dont need to save/restore the superclass fields in sub class but if you observe closely the writeExternal and readExternal methods of Car class closely, you will find that you still need to first call the super.xxxx() methods that confirms the statement the externalizable object must also coordinate with its supertype to save and restore its state.
Lets see the difference in sizes when you serialize using Serializable interface and serialize using Externalizable interface
Let's take a simple case, an object of type SimpleClass with just few fields - firstName, lastName, weight and location, containing data {"Brad", "Pitt", 180.5, {49.345, 67.567}}. When you serialize this object that is about 24 bytes by implementing Serializable interface, it turns into 220 bytes (approx). As it turns out, the basic serialization mechanism stores all kinds of information in the file so that it can deserialize without any other assistance. Look at the format below when the object is serialized and you will understand why it is turned out to 200 bytes.
 
Length: 220
Magic: ACED
Version: 5
  OBJECT
    CLASSDESC
    Class Name: "SimpleClass"
    Class UID:  -D56EDC726B866EBL
    Class Desc Flags: SERIALIZABLE;
    Field Count: 4
    Field type: object
    Field name: "firstName"
    Class name: "Ljava/lang/String;"
    Field type: object
    Field name: "lastName"
    Class name: "Ljava/lang/String;"
               Field type: float
    Field name: "weight"
    Field type: object
    Field name: "location"
    Class name: "Ljava/awt/Point;"
    Annotation: ENDBLOCKDATA
    Superclass description: NULL
   STRING: "Brad"
   STRING: "Pitt"
   float: 180.5
   OBJECT
      CLASSDESC
      Class Name: "java.awt.Point"
      Class UID:  -654B758DCB8137DAL
      Class Desc Flags: SERIALIZABLE;
      Field Count: 2
      Field type: integer
      Field name: "x"
      Field type: integer
      Field name: "y"
      Annotation: ENDBLOCKDATA
      Superclass description: NULL
     integer: 49.345
     integer: 67.567




Now if you serialize the same by extending Externalizable interface, the size will be reduced drastically and the information saved in the persistant store is also reduced a lot. Here is the result of serializing the same class, modified to be externalizable. Notice that the actual data is not parseable externally any more--only your class knows the meaning of the data!
 
Length: 54
Magic: ACED
Version: 5
  OBJECT
    CLASSDESC
    Class Name: "SimpleClass"
    Class UID:  5CB3777417A3AB5BL
    Class Desc Flags: EXTERNALIZABLE;
    Field Count: 0
    Annotation
      ENDBLOCKDATA
    Superclass description
      NULL
  EXTERNALIZABLE: 
   [70 00 04 4D 61 72 6B 00 05 44 61 76 69 73 43 3C
    80 00 00 00 00 01 00 00 00 01]



Well, externalization has its own limitations
Externalization efficiency comes at a price. The default serialization mechanism adapts to application changes due to the fact that metadata is automatically extracted from the class definitions (observe the format above and you will see that when the object is serialized by implementing Serializable interface, the class metadata(definitions) are written to the persistent store while when you serialize by implementing Externalizable interface, the class metadata is not written to the persistent store). Externalization on the other hand isn't very flexible and requires you to rewrite your marshalling and demarshalling code whenever you change your class definitions.
As you know a default public no-arg constructor will be called when serializing the objects that implements Externalizable interface. Hence, Externalizable interface can't be implemented by Inner Classes in Java as all the constructors of an inner class in Java will always accept the instance of the enclosing class as a prepended parameter and therefore you can't have a no-arg constructor for an inner class. Inner classes can achieve object serialization by only implementing Serializable interface.
If you are subclassing your externalizable class, you have to invoke your superclass’s implementation. So this causes overhead while you subclass your externalizable class. Observe the examples above where the superclass writeExternal method is explicitly called in the subclass writeExternal method.
Methods in externalizable interface are public. So any malicious program can invoke which results into loosing the prior serialized state.
Once your class is tagged with either Serializable or Externalizable, you can't change any evolved version of your class to the other format. You alone are responsible for maintaining compatibility across versions. That means that if you want the flexibility to add fields in the future, you'd better have your own mechanism so that you can skip over additional information possibly added by those future versions.
So much of it. Here are some final tips for serialization.
You can decide whether to implement Externalizable or Serializable on a class-by-class basis. Within the same application, some of your classes can be Serializable, and some can be Externalizable. This makes it easy to evolve your application in response to actual performance data and shifting requirements. You can do the following thing: 
* Make all your classes implement Serializable.
* Then make some of them, the ones you send often and for which serialization is inefficient, implement Externalizable instead.
To reduce memory size: 
* Write primitives or Strings directly. For example, instead of writing out a contained object, Point (in SimpleClass, we have a field of type Point), write out each of its integer coordinates separately. When you read them in, create a new Point from the two integers. This can be very significant in terms of size: an array of three Points takes 117 bytes; an array of 6 ints takes 51 bytes. 
* Strings are special-cased and don't carry much of the object overhead; you will normally use them as is. However, the serialized representation of a String is UTF, which works great for ASCII characters, is neutral for most European characters, but causes a 50% increase in size for Japanese and other scripts. If you have significant strings of Asian text you better serialize a char array instead.

1           Understanding Java Externalization with Examples

Last Updated on 19 March 2016   |    Print   Email
This article helps you understand about externalization in Java with code examples. You will be able to implement externalization in your Java programs.
 1. What is Externalization in Java?
In serialization, the Java Virtual Machine is totally responsible for the process of writing and reading objects. This is useful in most cases, as the programmers do not have to care about the underlying details of the serialization process. However, the default serialization does not protect sensitive information such as passwords and credentials, or what if the programmers want to secure some information during the serialization process?
Thus externalization comes to give the programmers full control in reading and writing objects during serialization.
 2. The Externalizable Interface
When you want to control the process of reading and writing objects during the serialization and de-serialization process, have the object’s class implemented the java.io.Externalizable interface. Then you implement your own code to write object’s states in the writeExternal() method and read object’s states in the readExternal() method. These methods are defined by the Externalizable interface as follows:
·         writeExternal(ObjectOutput out): The object implements this method to save its contents by calling the methods of DataOutput for its primitive values or calling the writeObject method of ObjectOutput for objects, strings, and arrays.

·         readExternal(ObjectInput in): The object implements this method to restore its contents by calling the methods of DataInput for primitive types and readObject for objects, strings and arrays.
Suppose that you have a class User, then implement externalization for this class as shown in the following example:
1
2
3
4
5
6
7
8
9
10
11
12
importjava.io.*;

/**
 * Externalization example
 * @author www.codejava.net
 */
publicclassUser implementsExternalizable {
    // attributes

    // methods

    // externalization methods:

    publicvoidwriteExternal(ObjectOutput out) {
        // implement your own code to write objects of this class
    }

    publicvoidreadExternal(ObjectInput in) {
        // implement your own code to read serialized objects of this class
    }
}

Now, let’s see how to implement the writeExternal() and readExternal() methods in details.
Suppose that the User class has the following attributes:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
importjava.util.*;
importjava.io.*;

/**
 * Externalization example
 * @author www.codejava.net
 */
Public   class   User   implements   Externalizable {
    Public  static  final   long   serialVersionUID = 1234L;

    // attributes
    Private   int  code;
    Private  String   name;
    Private   String    password;
    Private  Date   birthday;
    Private  int  socialSecurityNumber;

    publicUser() {
    }

    // methods (getters and setters)
    Public  int  getCode() {
        Return  this.code;
    }

    Public  void  setCode(int  code) {
        this.code = code;
    }

    Public   String   getName() {
        Return  this.name;
    }

    Public   void  setName(String    name) {
        this.name = name;
    }

    Public  String getPassword() {
        Return  this.password;
    }

    Public  void  setPassword(String   password) {
        this.password = password;
    }

    Public  void   setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    Public  Date getBirthday() {
        Return   this.birthday;
    }

    Public   void  setSocialSecurityNumber(intssn) {
        this.socialSecurityNumber = ssn;
    }

    publicintgetSocialSecurityNumber() {
        returnthis.socialSecurityNumber;
    }
}


NOTE: It’s strongly recommended that all serializable classes define the serialVersionUID constant as declared in the User class above:
1
publicstaticfinallongserialVersionUID = 1234L;
This helps the de-serialization process keeps re-constructing the objects correctly when the serializable classes get changed overtime, and avoid the InvalidClassException.
 3. Implementing writeExternal() method
As the writeExternal() method takes an ObjectOutput, we can use its method to write object’s states into the underlying stream follow these rules:
·         For primitive types, use the writeXXX() methods of the DataOutput interface, such as writeBoolean(), writeByte(), writeInt(), writeLong(), etc.
·         For object types (Strings, arrays, your custom classes), use the writeObject() method.
Following the above rules, we implement the writeExternal() method of the User class above like the following code:
1
2
3
4
5
6
7
8
9
10
publicvoidwriteExternal(ObjectOutput out) throwsIOException {
    out.writeInt(code);
    out.writeObject(name);

    // write empty password:
    out.writeObject("");

    out.writeObject(birthday);

}
As you can see, we serialize the following attributes: code, name, password and birthday. For security purpose, password is cleared and socialSecurityNumber is not serialized. This gives you the ideas of how we can control the process of serialization by implementing the Externalizable interface.
 4. Implementing readExternal() method
As the readExternal() method takes an ObjectInput, we can use its method to read object’s states from the underlying stream follow these rules:
·         For primitive types, use the readXXX() methods of the DataInput interface, such as readBoolean(), readByte(), readInt(), readLong(), etc.
·         For object types (Strings, arrays, your custom classes), use the readObject() method.
Following the above rules, we implement the readExternal() method of the User class above like the following code:
1
2
3
4
5
6
publicvoidreadExternal(ObjectInput in) throwsClassNotFoundException, IOException {
    this.code = in.readInt();
    this.name = (String) in.readObject();
    this.password = (String) in.readObject();
    this.birthday = (Date) in.readObject();
}
As you can see, we de-serialize the following attributes: code, name, password and birthday. The socialSecurityNumberis not de-serialized for security purpose. This gives you the ideas of how we can control the process of de-serialization by implementing the Externalizable interface.
 5. An Externalization Demo Program
Here’s the full source code of the demo program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
importjava.util.*;
importjava.io.*;

/**
 * Externalization Demo Program.
 * @author www.codejava.net
 */
publicclassExternalizationDemo {

    privateString filePath = "user.ser";

    publicvoidserialize() throwsIOException {
        User user = newUser();

        user.setCode(123);
        user.setName("Tom");
        user.setBirthday(newDate());
        user.setPassword("secret123");
        user.setSocialSecurityNumber(1234567890);


        // serialize object's state
        FileOutputStream fos = newFileOutputStream(filePath);
        ObjectOutputStream outputStream = newObjectOutputStream(fos);
        outputStream.writeObject(user);
        outputStream.close();


        System.out.println("User's details before serialization:\n"+ user);
        System.out.println("Serialization done");
    }

    publicvoiddeserialize() throwsClassNotFoundException, IOException {
        FileInputStream fis = newFileInputStream(filePath);
        ObjectInputStream inputStream = newObjectInputStream(fis);
        User user = (User) inputStream.readObject();
        inputStream.close();

        System.out.println("User's details afeter de-serialization:\n"+ user);
    }

    publicstaticvoidmain(String[] args)
            throwsClassNotFoundException, IOException {
        ExternalizationDemo demo = newExternalizationDemo();

        demo.serialize();

        System.out.println("\n=============\n");

        demo.deserialize();

    }

}


override the toString() method in the User class:
1
2
3
4
5
6
7
8
9
publicString toString() {
    String details = "Code: "+ code;
    details += "\nName: "+ name;
    details += "\nBirthday: "+ birthday;
    details += "\nPassword: "+ password;
    details += "\nSSN: "+ socialSecurityNumber;

    returndetails;
}
Run the above program and we have the following output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
User's details before serialization:
Code: 123
Name: Tom
Birthday: Sat Mar 19 15:12:27 ICT 2016
Password: secret123
SSN: 1234567890
Serialization done

=============

User's details afeter de-serialization:
Code: 123
Name: Tom
Birthday: Sat Mar 19 15:12:27 ICT 2016
Password:
SSN: 0
As you can see in the output, the password gets blank and social security number is reset after de-serialization.






Externalization in java

Limitations of Serialization
1)File size is very high
2)Customization due to transient which  is not effective because we get “null” in place of transient attributes.
3)while customizing we also get a metainformation of the file which includes when created who are eligible to read it etc: which is against data security.


Inorder to address these limitations of serialization,sun people came up with another I/O process named Externalization,which refers to dumping the state of an object in a permanent media using the interface Externalizable.

Externalizable is a sub-interface to Serializable but it is not a marker interface because it has two unimplemented methods readExternal() and writeExternal() which should be implemented by the classes which use Externalizable interface.

The process of externalization is same as that of serialization except the following:
1)Implementing writeExternal(ObjectOutput oout) & readExternal(ObjectInput oin) methods of Externalizable interface in a class which we want to externalize
2)Employing writeExternal() and readExternal() in place writeObject() & readObject() respectively.In block of writeExternal(),keep the attributes which we like to externalize
3)customization is very easy incase of externalization because whatever attributes we want to keep away from externalization just don’t keep them inside writeExternal() method block
4) In writeExternal() method block we make attributes externalized by using corresponding methods for different types of data. We should take care of IOException while using this method.

   Ex:writeInt(i)----------for integers
      writeDouble(d)------for doubles
      writeUTF(s)-------for strings
      writeObject(i)-------for derived attributes other than string& wrapper         
                              classes
UTF--Universal Text Format

5) using readExternal() method we can read the states of the object returned using the corresponding read methods stated above
6)flusing and closing operations are same to that of serialization
7)All the rules of derived attributes & Inheritance applied for serialization are also valid in case of Externalization.
8)If a class uses any derived attributes other than String & all Wrapper class attributes then that particular class also should be implemented with either Externalizable or Serializable interface.If we don’t do so, we get NotSerializableException

The main advantages of externalization over serialization are:
1)File size is highly reduced(nearly 1/3)
2) customization is very easy and more effective.

Java program to demonstrate Externalization
package com.usr.io;

import java.io.Externalizable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

class Employee implements Externalizable {
       String name;
       double salary;
       int age;
       long cardNo;

       public void writeExternal(ObjectOutput out) throws IOException {
              out.writeUTF(name);
              out.writeInt(age);
              out.writeDouble(salary);
       }
       public void readExternal(ObjectInput in) throws IOException,
                     ClassNotFoundException {
              name = in.readUTF();
              age = in.readInt();
              salary = in.readDouble();

       }
}
while writing whatever order we follow the same order must be followed in reading also.
public class ExternalizationDemo {
       public static void main(String[] args) {
              Employee emp = new Employee();
              emp.name = "Alex";
              emp.age = 26;
              emp.salary = 34567.8;
              emp.cardNo = 65754534;
              File file = new File("employee.ser");
              FileOutputStream fos = null;
              ObjectOutputStream oos = null;
              try {
                     fos = new FileOutputStream(file);
                     oos = new ObjectOutputStream(fos);
                     emp.writeExternal(oos);
                     System.out.println("object persisted");
              } catch (IOException ex) {
                     ex.printStackTrace();
              } finally {
                     try {
                           if (oos != null) {
                                  oos.flush();
                                  oos.close();
                           }
                     } catch (IOException ex) {
                           ex.printStackTrace();
                     }
                     try {
                           if (fos != null) {
                                  fos.flush();
                                  fos.close();
                           }
                     } catch (IOException ex) {
                           ex.printStackTrace();
                     }
              }
       }
}

 

No comments:

Post a Comment