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).
No,
you cannotoverridetheconstructorof theSuperclass.JVMwill definitely call thesuper class constructorwhile creating thechild class instance. So, whenever youcreateasubclass instance, it will invoke thebase class constructorand thencontinuewith thesubclass constructor statements.ConstructorsarenotMethodsthat can beoverridden
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.
Byoverriding,
what you achieve ?? A constructor must construct the current object.
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.
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.
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.
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.staticfinalint data;//static blank final variable
3.static{ data=50;}
4.publicstaticvoid 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.
What is difference
betweenfinal,finallyandfinalizemethod is asked to my friend in
aJava
interviewwith
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 worksand
one of the puzzle which is based on recursion. In shortfinalkeyword can be used along with
variable, method and class and has different meaning for all of them.finallyis another Java keyword which is
used in Exception handling along withtry,catch,throw
and throws.finalize()is
a special method in Java which is called byGarbage
Collectorbefore
reclaiming GC eligible objects. In this Java interview questions article we
will comparefinal
vs finally vs finalizeand
highlight some important difference betweenfinal,finallyandfinalizemethod in Java.
1.2final vs finally vs finalize in
Java
As I said earlierfinalkeyword can be used along with
variable, method andClass
in Java. If you make a variablefinal, you can not change it's
value, it will act like aconstant.finalvariables are initialized at the
time of creation except in case ofblank
final variablewhich
is initialized in Constructor. If you make a method final in Java, you can notoverrideit in sub class . If you make a
classfinalmeans 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 reasonWhy
String is final in Java. In short final is not related
at all with eitherfinallyorfinalizekeyword. 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 seeWhat
is final in Javafor
more information aboutfinalkeyword.
Now let's seeWhat is finally in Java?
As I saidfinallyis used for exception handling
along withtryandcatch. As per Java programming
language’s rule, for exception handling you at least need eithercatchorfinallyblock.finallyblock has special
advantage over catch that itsguaranteed
to be executeddespite
whether Exception is thrown or not, this makes it, an ideal place to close
system resource e.g.InputStreamorOutputStream, 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 usetry
with resource blockto
close resource automatically. Sincefinallyis guaranteed to be executed on
most cases, it also gives birth to sometricky
Java questionswhere
finally doesn't execute e.g. returning value from finally block, callingSystem.exitfrom try block etc.finallyblock always execute, except in
case of JVM dies i.e. callingSystem.exit(). Again finally is not related
tofinalorfinalizein any way.
Now let’s seeWhat isfinalize()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 onfinalizeby double checking
scarce resources. See10
points on finalize methodto
know more about specific points of finalize().
So,final,finallyandfinalizeall are different keyword, they
are used for different purpose. only similarity between them is that they are a
Java programming language keyword, other than thatfinal,finalizeandfinallyare 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.
2Exception
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.
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:
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.
Template Method
Pattern
Mediator Pattern
Chain of
Responsibility Pattern
Observer Pattern
Strategy Pattern
Command Pattern
State Pattern
Visitor Pattern
Iterator Pattern
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.
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 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(){
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.
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.
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 {
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 aShapeinterface and concrete classes
implementing theShapeinterface. A factory classShapeFactoryis defined as a next step.
FactoryPatternDemo, our demo class will useShapeFactoryto get aShapeobject. It will pass
information (CIRCLE / RECTANGLE / SQUARE) toShapeFactoryto 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.
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.
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");
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");
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 –
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.
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.
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 Externalizableinterface in Java:\
1. In
case of Serializable,default serialization
processis used. while in case of
Externalizable custom Serialization process is used whichis implemented by application.
2. JVM
gives call back toreadExternel()andwriteExternal()ofjava.io.Externalizalbeinterface for restoring and writing objects into
persistence.
3.Externalizableinterface provides complete control of serialization
process to application.
4.readExternal()andwriteExternal()supersede any specific implementation ofwriteObjectandreadObjectmethods.
Though
Externalizable provides complete control, it also presents challenges to
serialize super type state and take care of default values incase oftransient variableandstatic variables in Java. If used correctlyExternalizableinterface can improve performance of serialization
process.
That’s all onDifference between Externalizable and Serializable
interface in Java. This is always asked when Java interview take turn
towards Serialization afterMulti-Threading questionsandCollections 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 whatserializationis because externalization is
nothing but serialization but an alternative for it and Externalizable
interface extends Serializable interface. CheckSerializationarticle 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 isExternalization.
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
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 {
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.
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?
Inserialization, 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 thejava.io.Externalizableinterface. Then you implement your own code to write object’s states in thewriteExternal()method and read object’s states in thereadExternal()method. These methods are defined by theExternalizableinterface as follows:
·writeExternal(ObjectOutput out): The object implements this method to save its contents by calling the methods ofDataOutputfor its primitive values or calling thewriteObjectmethod ofObjectOutputfor objects, strings, and arrays.
·readExternal(ObjectInput in): The object implements this method to restore its contents by calling the methods ofDataInputfor primitive types andreadObjectfor objects, strings and arrays.
Suppose that you have a classUser, 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
*/
publicclassUserimplementsExternalizable {
// 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 thewriteExternal()andreadExternal()methods in details.
Suppose that theUserclass 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 Userimplements 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 theserialVersionUIDconstant as declared in theUserclass 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 theInvalidClassException.
3. Implementing writeExternal() method
As thewriteExternal()method takes anObjectOutput, we can use its method to write object’s states into the underlying stream follow these rules:
·For primitive types, use thewriteXXX()methods of theDataOutputinterface, such aswriteBoolean(),writeByte(),writeInt(),writeLong(), etc.
·For object types (Strings, arrays, your custom classes), use thewriteObject()method.
Following the above rules, we implement thewriteExternal()method of theUserclass above like the following code:
As you can see, we serialize the following attributes: code, name, password and birthday. For security purpose, password is cleared andsocialSecurityNumberis not serialized. This gives you the ideas of how we can control the process of serialization by implementing theExternalizableinterface.
4. Implementing readExternal() method
As thereadExternal()method takes anObjectInput, we can use its method to read object’s states from the underlying stream follow these rules:
·For primitive types, use thereadXXX()methods of theDataInputinterface, such asreadBoolean(),readByte(),readInt(),readLong(), etc.
·For object types (Strings, arrays, your custom classes), use thereadObject()method.
Following the above rules, we implement thereadExternal()method of theUserclass above like the following code:
As you can see, we de-serialize the following attributes: code, name, password and birthday. ThesocialSecurityNumberis not de-serialized for security purpose. This gives you the ideas of how we can control the process of de-serialization by implementing theExternalizableinterface.
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:
No comments:
Post a Comment