X

Play AlgoQuiz

Rate Us :



Share with Friends :

Menu

InputStreamReader :

An InputStreamReader is a bridge from byte stream to character stream. It reads byte and decode them into characters using a specified character set.


Constructor for InputStreamReader class :


InputStreamReader(InputStream in) :-

This constructor creates an InputStreamReader that uses the default character set.

Example :

import java.io.*; class Example { public static void main(String[ ] args) throws Exception { InputStreamReader ir = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(ir); System.out.print("Input data : "); String s = br.readLine(); System.out.println("Inputed data is " + s); br.close(); ir.close(); } } //save as : Example.java //compile as : javac Example.java //run as : java Example

Output :

Input data : Algovalley Inputed data is Algovalley

PrintStream :

A PrintStream adds functionality to another output stream to print representations of various data values conveniently. It is a FilteredOutputStream and never throws an IOException. PrintStream reference is used for designing user defined system class.


Constructors for PrintStream class :


PrintStream(OutputStream out) :-

This constructor creates a new PrintStream.


PrintStream(String file_name) :-

This constructor creates a new PrintStream without automatic line flushing with the specified file name.


Methods in PrintStream class :


  • print()




  • println()




  • printf()




Example1 :

import java.io.*; class Example { public static void main(String[ ] args) throws Exception { FileOutputStream fw = new FileOutputStream("file5.txt"); PrintStream ps = new PrintStream(fw); ps.println(65); ps.println(10.5); ps.println(true); ps.println("Algo"); ps.close(); fw.close(); } } //save as : Example.java //compile as : javac Example.java //run as : java Example

Output :

65 10.5 true Algo

Example2 :

import java.io.*; class Algo { static PrintStream out; static { try { out = new PrintStream("con"); } catch(Exception e) { } } } class Example { public static void main(String[ ] args) throws Exception { Algo.out.println("Java"); Algo.out.println("Program"); } } //save as : Example.java //compile as : javac Example.java //run as : java Example

Output :

Java Program

Serialization :

Let us consider that there exists an object in the main memory (primary memory) with 'n' bytes of data. If we want to transfer 'n' bytes of data of object from main memory (primary memory) to the file of secondary memory by using either byte stream or character stream then we have to perform either 'n' redundant write operations or 'n/2' redundant operations. In such process the application will take more amount of time. In order to eliminate such problem and for enhancing the performance of streams we have a concept called Serialization. In Serialization concept, by performing single write operation we can transfer entire data of object into the file of secondary memory. It can eliminate redundant write operation and it perform single write operation. It is a process of writing state of object to a file. In technical sense it is a process of converting an object from Java supported form to either file supported form or network supported form. It is introduced in version 1.1 of Java.


Requirement for Serialization :-


  • We can perform Serializable only for Serializable objects.

  • An object to be Serializable, it's class should implement Serializable interface once along the class hierarchy and it's class should also provide default constructor (a constructor with no argument).

  • Serializable interface is present in java.io package and it does not contain any method hence it is a marker interface.

  • By using FileOutputStream and ObjectOutputStream classes we can achieve Serialization.

ObjectOutputStream :

An ObjectOutputStream class writes primitive data types and graphs of Java objects to an output stream. It is a dependent stream. The object can be reconstituted or read using an ObjectInputStream class.


Constructor for ObjectOutputStream :


ObjectOutputStream(OutputStream out) :-

This constructor is used to create an ObjectOutputStream that writes to the specified output stream.


Method for ObjectOutputStream :


void writeObject(Object obj) :-

This is a method used to write the specified object to the ObjectOutputStream.


Note :

Most of Java classes are Serializable. But objects of some system level classes are not Serializable (Non-Serializable objects) because the data they represent constantly changes. If we reconstruct the object then it contain different value.

For example, thread running in one JVM would be using one system memory. Persisting it and trying to run it in other JVM would make no sense at all.

A NotSerializableException is thrown if we try to serialize non-Serializable objects.


De-Serialization :

We know that a file is a collection of records and a record is a collection of field values. If we want to transfer the entire content of a record of a file which is containing 'n' bytes and if we used byte stream or character stream then we have to perform either 'n' read operation or 'n/2' read operations which is a process which consume lots of execution time. In order to eliminate such problem we used the concept of De-Serialization. It transfer the record of a file of secondary memory into main memory (i.e. primary memory) with the help of single read operation irrespective of number of bytes present in the record i.e. it eliminates redundant read operation. It is a process of reading state of an object from a file. In technical sense it is a process of converting an object from either network supported form or file supported form to Java supported form.


Requirement for De-Serialization :-


  • By using FileInputStream and ObjectInputStream classes we can achieve De-Serialization.

Example :

import java.io.*; class Algo implements Serializable { int a = 10; int b = 20; } class Example { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo(); FileOutputStream fw = new FileOutputStream("data2.ser"); ObjectOutputStream dos = new ObjectOutputStream(fw); dos.writeObject(obj1); FileInputStream fr = new FileInputStream("data2.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.a + " " + obj2.b); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data2 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

10 20 Object information will be stored in data2 file as binary data.

transient keyword :

At the time of Serialization if we don't want to serialize the value of a particular variable to meet the security constraint, we have to declare those variables with 'transient' keyword. At the time of Serialization, JVM ignores original value of transient variable and save default value. We can use transient keyword only for variables but not for methods because methods are not a part of serialized stream.


Syntax :

transient data_type variable_name;

Example :

import java.io.*; class Algo implements Serializable { int a = 10; transient int b = 20; } class Example { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo(); FileOutputStream fw = new FileOutputStream("data3.ser"); ObjectOutputStream dos = new ObjectOutputStream(fw); dos.writeObject(obj1); FileInputStream fr = new FileInputStream("data3.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.a + " " + obj2.b); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data3 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

10 0 Object information will be stored in data3 file as binary data.

Note :

  • Static variables are not a part of object so it can't participate in Serialization process. Due to this declaring a static variable as transient will not show any changes.

  • Final variables will participate in Serialization directly by their values. Due to this declaring a final variable with transient will not show any changes.

Syntax :

transient data_type variable_name;

Example1 :

import java.io.*; class Algo implements Serializable { int a = 10; transient static int b = 20; } class Example { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo(); FileOutputStream fw = new FileOutputStream("data3.ser"); ObjectOutputStream dos = new ObjectOutputStream(fw); dos.writeObject(obj1); FileInputStream fr = new FileInputStream("data3.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.a + " " + obj2.b); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data3 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

10 20 Object information will be stored in data3 file as binary data.

Example2 :

import java.io.*; class Algo implements Serializable { int a = 10; transient final int b = 20; } class Example { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo(); FileOutputStream fw = new FileOutputStream("data3.ser"); ObjectOutputStream dos = new ObjectOutputStream(fw); dos.writeObject(obj1); FileInputStream fr = new FileInputStream("data3.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.a + " " + obj2.b); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data3 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

10 20 Object information will be stored in data3 file as binary data.

Types of Serialization :


  • Complete Serialization




  • Selective Serialization




Complete Serialization :-

In complete Serialization, all the data members of Serializable subclass participates in Serialization process.


Selective Serialization :-

In selective Serialization, some of the data members of Serializable subclass participates in Serialization process and some of the data members will not participate in Serialization.

Data members which won't participate in Serialization will have to be preceded by transient keyword.


Object Graph in Serialization :

Whenever we are trying to serialize an object then a set of all objects which are reachable from that object will be serialized automatically. This set of objects are called object graph.

Example :

import java.io.*; class Algo implements Serializable { Java obj3 = new Java(); } class Java implements Serializable { Valley obj4 = new Valley(); } class Valley implements Serializable { int a = 10; } class Example { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo(); FileOutputStream fw = new FileOutputStream("data4.ser"); ObjectOutputStream d = new ObjectOutputStream(fw); d.writeObject(obj1); FileInputStream fr = new FileInputStream("data4.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.obj3.obj4.a); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data4 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

10 Object information will be stored in data4 file as binary data. Note : Here, when we are serializing Algo object then automatically Java and Valley objects will be serialized because they both are the part of object graph of Algo object. If even one of the class (Algo , Java , Valley) is not Serializable then we will get runtime error saying NotSerializableException.

Customized Serialization :

In the default Serialization there may be a chance of loss of information because of transient keyword.

Example :

import java.io.*; class Algo implements Serializable { String s1 = "Java"; transient String s2 = "Program"; } class Example { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo(); System.out.println(obj1.s1 + " " + obj1.s2); FileOutputStream fw = new FileOutputStream("data5.ser"); ObjectOutputStream dos = new ObjectOutputStream(fw); dos.writeObject(obj1); FileInputStream fr = new FileInputStream("data5.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.s1 + " " + obj2.s2); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data5 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

Java Program Java null Object information will be stored in data5 file as binary data.

In the above example, before Serialization we can obtain the value of s1 and s2. But after De-Serialization we can't obtain original value of s2 because JVM will return default value of s2 (i.e. null). Hence, during default Serialization there is a chance of loss of information which can be handled using customized Serialization.

We can implement customized Serialization by using following two methods :-

private void writeObject(ObjectOutputStream oos) throws Exception
/*this method will be executed automatically at the time of Serialization by the JVM 
(any method executed automatically by the JVM is by default considered as callback method).*/

private void readObject(ObjectInputStream ois) throws Exception
/*this method will be executed automatically at the time of De-Serialization by the JVM 
(any method executed automatically by the JVM is by default considered as callback method).*/
 

Example :

import java.io.*; class Algo implements Serializable { String s1 = "Java"; transient String s2 = "Program"; private void writeObject(ObjectOutputStream oos) throws Exception { oos.defaultWriteObject(); String s3 = "Sample" + s2; oos.writeObject(s3); } private void readObject(ObjectInputStream ois) throws Exception { ois.defaultReadObject(); String s3 = (String) ois.readObject(); s2 = s3.substring(6); } } class Example { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo(); System.out.println(obj1.s1 + " " + obj1.s2); FileOutputStream fw = new FileOutputStream("data5.ser"); ObjectOutputStream dos = new ObjectOutputStream(fw); dos.writeObject(obj1); FileInputStream fr = new FileInputStream("data5.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.s1 + " " + obj2.s2); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data5 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

Java Program Java Program Object information will be stored in data5 file as binary data.

Serialization with respect to Inheritance :

If the parent class implements Serializable then every child class is by default Serializable i.e. Serializable nature is inherited from parent to child class.

Example :

import java.io.*; class Algo implements Serializable { int a = 10; } class Valley extends Algo { int b = 20; } class Example { public static void main(String[ ] args) throws Exception { Valley obj1 = new Valley(); FileOutputStream fw = new FileOutputStream("data6.ser"); ObjectOutputStream d = new ObjectOutputStream(fw); d.writeObject(obj1); FileInputStream fr = new FileInputStream("data4.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Valley obj2 = (Valley) dis.readObject(); System.out.println(obj2.a + " " + obj2.b); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data6 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

10 20 Object information will be stored in data6 file as binary data. Note : We can serialize Valley object even though Valley class doesn't implement Serializable interface explicitly because it's parent class Algo has implement Serializable.

Even though parent class doesn't implement Serializable and the child class is Serializable then we can serialize child class object. At the time of Serialization JVM ignores the original values of instance variables which are coming from non-Serializable parent class and store default values. At the time of De-Serialization JVM will check for any parent class which is non-Serializable and then creates a separate object for every non-Serializable parent class and share it's instance variables to the current object. For this JVM always calls no argument constructor (either compiler generated default constructor or programmer provided no argument constructor) of the non-Serializable parent class. If the non-Serializable parent class doesn't have no argument constructor then we will get runtime exception saying InvalidClassException.

Example :

import java.io.*; class Algo { int a = 10; } class Valley extends Algo implements Serializable { int b = 20; } class Example { public static void main(String[ ] args) throws Exception { Valley obj1 = new Valley(); obj1.a = 30; obj1.b = 40; FileOutputStream fw = new FileOutputStream("data6.ser"); ObjectOutputStream d = new ObjectOutputStream(fw); d.writeObject(obj1); FileInputStream fr = new FileInputStream("data6.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Valley obj2 = (Valley) dis.readObject(); System.out.println(obj2.a + " " + obj2.b); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data6 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

10 40 Object information will be stored in data6 file as binary data.

serialVersionUID :

In Serialization both sender and receiver may not be same and may not be from the same location and may not use same machine. Persons may be different, locations may be different and machines may be different.

At the time of Serialization JVM will save a unique ID with every object. This unique ID will be generated by JVM based on .class file. At the time of De-Serialization receiver side JVM will compare object unique ID with local .class unique ID. If both are matched then only De-Serialization will be performed otherwise receiver unable to De-Serialize and we will get runtime exception saying InvalidClassException. This unique identifier is nothing but serialVersionUID.


The problem of depending on default serialVersionUID generated by JVM are :

Both sender and receiver should use same JVM with respect to vendor and version. If there is any incompatibility in JVM versions then receiver is unable to De-Serialize because of different serialVersionUID. In this case receiver will get runtime exception saying InvalidClassException. After Serialization if we change .class file at receiver side then we can't perform De-Serialization because of mismatch in serialVersionUID of local class of receiver and Serialized object. In this case at the time of De-Serialization we will get runtime exception saying InvalidClassException. To generate serialVersionUID internally JVM will use complex algorithm which may create performance problems. We can solve this problems by configuring our own serialVersionUID. We can configure serialVersionUID as follows :

 private static final long serialVersionUID = 1L;
 

Example :

import java.io.Serializable; class Algo implements Serializable { private static final long serialVersionUID = 1L; int i = 10; int j = 20; }


import java.io.*; class Sender { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo(); FileOutputStream fw = new FileOutputStream("data7.ser"); ObjectOutputStream d = new ObjectOutputStream(fw); d.writeObject(obj1); } }


import java.io.*; class Receiver { public static void main(String[ ] args) throws Exception { FileInputStream fr = new FileInputStream("data7.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.i + " " + obj2.j); } } //Follow following sequence of execution of Algo, Sender , Receiver classes : //javac Algo.java //javac Sender.java //javac Receiver.java /*Then a file will be generated by the name of data7 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/


//Then do some modification in Algo.java import java.io.Serializable; class Algo implements Serializable { private static final long serialVersionUID = 1L; int i = 10; int j = 20; int k = 30; int l = 40; } //javac Algo.java //java Receiver

Output :

10 20 Object information will be stored in data7 file as binary data. Note : Here, after Serialization even though if we are performing any change in the .class file we can De-Serialize object. If we configure our own serialVersionUID both sender and receiver are not required to maintain same JVM versions.

Note :

Some IDE's explicitly prompt the programmer to enter serialVersionUID.

Some IDE's may generate explicit serialVersionID automatically instead of depending on JVM generated default serialVersionUID.


Externalization :

In Serialization everything takes care by JVM and programmer doesn't have any control. In Serialization total object will be saved always to the file and it is not possible to save part of the object which creates performance problem. To overcome this problem we should go for Externalization where everything takes care by programmer and JVM doesn't have any control. The main advantage of Externalization over Serialization is based on our requirement we can save either total object or part of the object so that relatively performance will be improved. To provide Externalizable ability for any Java object it is compulsory that the corresponding class should implements Externalizable interface. It is introduced in version 1.1 of Java.

Externalizable interface present in java.io package and it is the child interface of Serializable interface. Externalizable interface contains two methods :

  • writeExternal()




  • readExternal()




public void writeExternal(ObjectOutput out) throws IOException :-

This method will be executed automatically at the time of Serialization. Within this method we have to write code to save required variables to the file.


public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException :-

This method will be executed automatically at the time of De-Serialization. Within this method we have to write code to read required variables from the file and assign to the current object. At the time of De-Serialisation JVM will create a separate new object by executing public no-argument constructor. On that object readExternal() method will be executed. Hence every Externalizable interface implemented class should compulsory contain public no-argument constructor otherwise we will get runtime exception saying InvalidClassException.

Example :

import java.io.*; class Algo implements Externalizable { String s; int i; int j; public Algo() { System.out.println("Public no-argument constructor"); } Algo(String s , int i , int j) { this.s = s; this.i = i; this.j = j; } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(s); out.writeInt(i); } public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException { s = (String) in.readObject(); i = in.readInt(); } } class Example { public static void main(String[ ] args) throws Exception { Algo obj1 = new Algo("Valley" , 10 , 20); FileOutputStream fw = new FileOutputStream("data8.ser"); ObjectOutputStream d = new ObjectOutputStream(fw); d.writeObject(obj1); FileInputStream fr = new FileInputStream("data8.ser"); ObjectInputStream dis = new ObjectInputStream(fr); Algo obj2 = (Algo) dis.readObject(); System.out.println(obj2.s + " " + obj2.i + " " + obj2.j); } } //save as : Example.java //compile as : javac Example.java //run as : java Example /*Then a file will be generated by the name of data8 if it already exists then it will be overwritten located in the same directory in which the Example.java file is stored.*/

Output :

Public no-argument constructor Valley 10 0 Object information will be stored in data8 file as binary data. Note : If the class implement Serializable interface then the total object will be saved to the file and output will be : Valley 10 20 If the class implements Externalizable interface then part of the object will be saved to the file and output will be : Public no-argument constructor Valley 10 0

Note :

transient keyword play role only in Serialization and it won't play any role in Externalization. Of course, transient keyword is not required in Externalization.

If all variables declared as transient in the previous example and if class implements Serializable then the output will be :

null 0 0 
 

If all variables declared as transient in the previous example and if class implements Externalizable then the output will be :

Public no-argument constructor
Valley 10 0


X

MiniDoll :

MiniDoll is an application to learn with fun. You can play it to solve some tricky questions related to Java Programming. Either enjoy playing it alone or discuss with your friends to solve it. It is a simple approach to learn by solving questions. This application has different topics of Java and each topic is divided into three phases. Start solving from initial topic to final topic and by the end of every topic you can boost your concept of that topic.