Friday, 5 October 2018

Immutable Class & Objects


Immutable objects are instances whose state doesn’t change after it has been initialized. For example, String is an immutable class and once instantiated its value never changes.

Example:
public final class Color
{
   final private int red;
   final private int green;
   final private int blue;
   private void check(int red, int green, int blue) 
   {
       if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) 
       {
              throw new IllegalArgumentException();
        }
    }
    public Color(int red, int green, int blue) 
    {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
     }
     public Color invert() 
     {
            return new Color(255,255,255 );
     }
}
Advantage Of Immutability:
The advantage of immutability comes with concurrency. It is difficult to maintain correctness in mutable objects, as multiple threads could be trying to change the state of the same object, leading to some threads seeing a different state of the same object, depending on the timing of the reads and writes to the said object.
By having an immutable object, one can ensure that all threads that are looking at the object will be seeing the same state, as the state of an immutable object will not change.

Rules to define immutable classes:
The following rules define a simple strategy for creating immutable objects.
  • Don't provide "setter" methods - methods that modify fields or objects referred to by fields.
  • Make all fields final and private. Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
  • If the instance fields include references to mutable objects, don't allow those objects to be changed
  • Don't provide methods that modify the mutable objects.
  • Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
Immutable Objects:
An immutable object is an object whose state cannot be changed. An immutable class is a class whose instances are immutable by design, and implementation. The Java class which is most commonly presented as an example of immutability is java.lang.String.
Some basic types and classes in Java are fundamentally mutable. For example, all array types are mutable, and so are classes like java.util.Data. This can be awkward in situations where an immutable type is mandated. One way to deal with this is to create an immutable wrapper for the mutable type. Here is a simple wrapper for an array of integers
Example:
public class ImmutableIntArray 
{
   private final int[] array;
   public ImmutableIntArray(int[] array) 
   {
        this.array = array.clone();
   }
   public int[] getValue() 
   {
      return this.clone();
   }
}
This class works by using defensive copying to isolate the mutable state (the int[]) from any code that might mutate it:
  • The constructor uses clone() to create a distinct copy of the parameter array. If the caller of the constructor subsequent changed the parameter array, it would not affect the state of the ImmutableIntArray.
  • The getValue() method also uses clone() to create the array that is returned. If the caller were to change the result array, it would not affect the state of the ImmutableIntArray.

We could also add methods to ImmutableIntArray to perform read-only operations on the wrapped array; e.g. get its length, get the value at a particular index, and so on.
Note that an immutable wrapper type implemented this way is not type compatible with the original type. You cannot simply substitute the former for the latter.

Points to consider to create Immutable Object:
  •  All properties must be set in the constructor(s) or factory method(s).There should be no setters.
  • If it is necessary to include setters for interface compatibility reasons, they should either do nothing or throw an exception.
  •  All properties should be declared as private and final.
  • For all properties that are references to mutable types: 
    • the property should be initialized with a deep copy of the value passed via the constructor
    • the property's getter should return a deep copy of the property value.
  • The class should be declared as final to prevent someone creating a mutable subclass of an immutable class.
A couple of other things to note:
  • Immutability does not prevent object from being nullable; e.g. null can be assigned to a String variable.
  • If an immutable classes properties are declared as final, instances are inherently thread-safe. This makes immutable classes a good building block for implementing multi-threaded applications.


Wednesday, 3 October 2018

Just-In-Time (JIT) compiler

The Just-In-Time (JIT) compiler is a component of the Java™ Runtime Environment that improves the performance of Java applications at run time. Java programs consists of classes, which contain platform-neutral bytecodes that can be interpreted by a JVM on many different computer architectures. At run time, the JVM loads the class files, determines the semantics of each individual bytecode, and performs the appropriate computation. The additional processor and memory usage during interpretation means that a Java application performs more slowly than a native application. The JIT compiler helps improve the performance of Java programs by compiling bytecodes into native machine code at run time.

The JIT compiler is enabled by default, and is activated when a Java method is called. The JIT compiler compiles the bytecodes of that method into native machine code, compiling it "just in time" to run. When a method has been compiled, the JVM calls the compiled code of that method directly instead of interpreting it. Theoretically, if compilation did not require processor time and memory usage, compiling every method could allow the speed of the Java program to approach that of a native application. JIT compilation does require processor time and memory usage. When the JVM first starts up, thousands of methods are called. Compiling all of these methods can significantly affect startup time, even if the program eventually achieves very good peak performance.

  • In practice, methods are not compiled the first time they are called. For each method, the JVM maintains a call count which is incremented every time the method is called.
  • The JVM interprets a method until its call count exceeds a JIT compilation threshold.
  • Therefore, often-used methods are compiled soon after the JVM has started, and less-used methods are compiled much later, or not at all.
  • The JIT compilation threshold helps the JVM start quickly and still have improved performance.
  • The threshold has been carefully selected to obtain an optimal balance between startup times and long term performance.
  • After a method is compiled, its call count is reset to zero and subsequent calls to the method continue to increment its count.
  • When the call count of a method reaches a JIT recompilation threshold, the JIT compiler compiles it a second time, applying a larger selection of optimizations than on the previous compilation.
  • This process is repeated until the maximum optimization level is reached

The busiest methods of a Java program are always optimized most aggressively, maximizing the performance benefits of using the JIT compiler. The JIT compiler can also measure operational data at run time, and use that data to improve the quality of further recompilations. The JIT compiler can be disabled, in which case the entire Java program will be interpreted. Disabling the JIT compiler is not recommended except to diagnose or work around JIT compilation problems.

Serialization

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 is used when you want to persist the object. It is also used by Java RMI to pass objects between JVMs, either as arguments in a method invocation from a client to a server or as return values from a method invocation, or as exceptions thrown by remote methods. In general, serialization is used when we want the object to exist beyond the lifetime of the JVM.

java.io.Serializable is a marker interface (has no body). It is just used to "mark" Java classes as serializable.

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during de-serialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long:

       <<accessSpecifier>>  static final long serialVersionUID = 1L;

How to make a class eligible for serialization
To persist an object the respective class must implement the java.io.Serializable interface.

import java.io.*;
public class SerialClass implements Serializable 
{
    private static final long serialVersionUID = 1L;
    private Date currentTime;
    public SerialClass() 
    {
      currentTime = Calendar.getInstance().getTime();
    }
    public Date getCurrentTime() 
    {
       return currentTime;
    }
}

How to write an object into a file
Now we need to write this object to a file system. We use java.io.ObjectOutputStream for this purpose.
import java.io.*;
public class PersistSerialClass 
{
   public static void main(String [] args) 
   {
      String filename = "time.ser";
      //We will write this object to file system.
      SerialClass time = new SerialClass(); 
      try
      {
 ObjectOutputStream out;
         out= new ObjectOutputStream(new FileOutputStream(filename));
         out.writeObject(time); //Write byte stream to file system.
         out.close();
       }
       catch(IOException ex)
       {
             ex.printStackTrace();
       }
   }
}

How to recreate an object from its serialized state
The stored object can be read from file system at later time using java.io.ObjectInputStream as shown below:
import java.io.*;
public class ReadSerialClass 
{
     public static void main(String [] args) 
     {
         String filename = "time.ser";
         SerialClass time = null;
         try 
         {
              ObjectInputStream in;
              in= new ObjectInputStream(new FileInputStream(filename));
              time = (SerialClass)in.readObject();
              in.close();
          } 
          catch(Exception ex)
          {
               ex.printStackTrace();
           } 
          // print out restored time
           System.out.println ("Restored time: " + time.getTime());
      }
}

Note: Serializing an object serializes the entire object graph of which it is the root, and operates correctly in the presence of cyclic graphs. A reset() method is provided to force the ObjectOutputStream to forget about objects that have already been serialized.

Monday, 24 September 2018

Java File I/O

In order to read/ write into or from files java provides basically three ways 

  1. Reading /Writing bytes
  2. Reading/ Writing Characters
  3. Reading/ Writing Primitive data

Reading / Writing Bytes: Java provides FileInputStream and FileOutputStream to read/ write bytes from or into the files.
FileInputStream:
 It is a byte input stream derived from InputStream used to read from disk file in form of bytes.
Constructors: 
FileInputStream (String filename):  constructs a FileInputStream object using the file name given as String.
FileInputStream (File filename):  constructs a FileInputStream object using the file name given as File object.
Eg:
String    file=”Sample.txt”;
FileInputStream    fis=new FileInputStream (file);
int  ch;
while((ch=fis.read())!=-1)
System.out.print((char)ch);
fis.close();

FileOutputStream:
It is a byte output stream derived from OutputStream used to write data to a disk file in form of bytes.
Constructor: 
FileOutputStream (String filename):  constructs a FileOutputStream object using the file name given as String.
FileOutputStream (File filename):  constructs a FileOutputStream object using the file name given as File object.
Eg: 
String    file=”Sample.txt”;
FileOutputStream    fos=new FileOutputStream (file);
byte   b[]=”This is a sample program”.getBytes();
for(int i=0;i<b.length;i++)
fos.write(b[i]);
fos.close();

Note: The FileInputStream and FileOutputStream throw two checked exceptions namely FileNotFoundException and IOException. 

Reading / Writing Characters:
Java provides FileReader and FileWriter to read/ write characters from or into the files.
FileReader:
 It is a character input stream derived from Reader used to read from disk file in form of characters.
Constructors: 
FileReader (String filename):  constructs a FileReader object using the file name given as String.
FileReader (File filename):  constructs a FileReader object using the file name given as File object.
Eg:
String    file=”Sample.txt”;
FileReader    fr=new FileReader (file);
int  ch;
while((ch=fr.read())!=-1)
System.out.print((char)ch);
fr.close();

FileWriter:
It is a character output stream derived from Writer used to write data to a disk file in form of characters.
Constructors: 
FileWriter (String filename):  constructs a FileWriter object using the file name given as String.
FileWriter (File filename):  constructs a FileWriter object using the file name given as File object.
Eg:  
String    file=”Sample.txt”;
FileWriter fw=new FileWriter (file);
char   c[]=”This is a sample program”.toCharArray();
for(int i=0;i<c.length;i++)
fw.write(c[i]);
fw.close();
Note: The FileReader and FileWriter throw two checked exceptions namely FileNotFoundException and IOException. 

Reading / Writing Primitive data types:
                Java provides DataInputStream and DataOutputStream inorder to read or write primitive data from or into the Files.
DataInputStream:
                It is a byte filter stream which is used to read data in required format. It requires a node stream to process.
Constructors:
DataInputStream(InputStream is): creates a DataInputStream object for the specified byte input stream.
DataInputStream provides methods to read required format of the data from an output stream


Method
Description
int read(byte[] b)
It is used to read the number of bytes from the input stream.
int read(byte[] b, int off, int len)
It is used to read len bytes of data from the input stream.
int readInt()
It is used to read input bytes and return an int value.
byte readByte()
It is used to read and return the one input byte.
char readChar()
It is used to read two input bytes and returns a char value.
double readDouble()
It is used to read eight input bytes and returns a double value.
boolean readBoolean()
It is used to read one input byte and return true if byte is non zero, false if byte is zero.
int skipBytes(int x)
It is used to skip over x bytes of data from the input stream.
String readUTF()
It is used to read a string that has been encoded using the UTF-8 format.
void readFully(byte[] b)
It is used to read bytes from the input stream and store them into the buffer array.
void readFully(byte[] b, int off, int len)
It is used to read len bytes from the input stream.

Eg:          String    file=”StudentDetails.txt”;

FileInputStream    fis=new FileInputStream (file);
DataInputStream  dis=new  DataInputStream(fis);
                int   rNo=dis.readInt();
                String  name=dis.readLine();
                float  marks=dis.readFloat();
                dis.close();
                fis.close():

DataOutputStream:
                It is a byte filter stream which is used to read data in required format. It requires a node stream to process.
Constructors:
DataOutputStream(OutputStream is): creates a DataOutputStream object for the specified byte input stream.
DataOutputStream provides methods to write required format of the data to an output stream
Method
Description
int size()
It is used to return the number of bytes written to the data output stream.
void write(int b)
It is used to write the specified byte to the underlying output stream.
void write(byte[] b, int off, int len)
It is used to write len bytes of data to the output stream.
void writeBoolean(boolean v)
It is used to write Boolean to the output stream as a 1-byte value.
void writeChar(int v)
It is used to write char to the output stream as a 2-byte value.
void writeChars(String s)
It is used to write string to the output stream as a sequence of characters.
void writeByte(int v)
It is used to write a byte to the output stream as a 1-byte value.
void writeBytes(String s)
It is used to write string to the output stream as a sequence of bytes.
void writeInt(int v)
It is used to write an int to the output stream
void writeShort(int v)
It is used to write a short to the output stream.
void writeShort(int v)
It is used to write a short to the output stream.
Eg:         
         String    file=”StudentDetails.txt”;
FileOutputStream    fos=new FileOutputStream (file);
DataOutputStream  dis=new  DataOutputStream(fos);
                int   rNo =1234;
                String  name=”ramu”;
                float  marks=789F;
                dos.writeInt(rNo);
                dos.writeChars(name);
                dos.writeFloat(marks);
                dis.close();
                fis.close():

Saturday, 22 September 2018

Characters Streams

Streams:
         Streams are used to transfer the data between program and source/destination. They transfer the data in unique way irrespective of source/destination. Streams are defined in java.io package in java. Depending up on the direction of the transfer the streams are classified in to two categories.
  • Input Stream: These streams carry the data from some source in to the program. The source may be a keyboard, a file …Here read operation is performed to input the data in to the program.
  • Output Stream: They carry the data from program to some destination. The destination may be a monitor, printer, a file … Here write operation is performed to send data from the program.
Streams that carry the data in form of characters into the program from a source or from a program to These streams carry the data in the form of chars. They use 16 bit (2 bytes) of storage to read the data. Character streams are not present form the first version of the java they are added after JDK 1.1 only. Reader is the base class for all character input streams and Writer is the base class for all character output streams.
Reader:
Reader is an abstract class and is the base class for all character input streams. Since it is abstract class objects cannot be created for Reader class. This class defines various methods which can be used in all character input streams. 
Methods:
  • int   read(): Reads next char from the stream as integer and returns -1 if no data is available in the stream.
  • int    read(char  c[]): Reads an array full of characters from the stream and returns actual number of characters read.
  • int    read(char c[], int start, int end): Reads character in to array from the specified start and end position form the stream.
  • long   available(): Returns how many number of characters yet to be read in the stream.
  • long  skip(long  n): Skips specified number of characters in the input stream and returns actual number of characters skipped
  • void  mark(int readLimit): Marks the current position and it is valid till specified read limit.
  • boolean  isMarkSupported(): Checks whether the Stream supports the mark facility or not
  • void  reset(): Moves to the recent marked position or beginning of the stream
  • void close(): Closes the stream.
Character Input Streams Hierarchy:

Stream Class Name
Use
FileReader
used to read from files
PipedReader
used to read from pipes
CharArrayReader
used to read from a char array
StringReader
used to read from a String
InputStreamReader
used to convert byte stream to character stream
BufferedReader
provides buffer facility to the Reader
PushBackReader
provides un reading facility to the Reader

Writer:
Writer is base class for all character output streams and it an abstract class. Writer defines a set of methods which are used to write the data into the streams.

Methods:
  • void    write(int c): Writes one character to output stream.
  • void     write(char c[]): Writes an array full of characters to output stream.
  • void    write(char  c[], int start, int end): Writes characters from array to output stream from the specified start and end position.
  • void  flush(): Flushes the stream i.e., immediately releases the pending data from stream.
  • void close(): Closes the output stream.
Character Output Streams Hierarchy:
Stream Class Name
Use
FileWriter
used to write data into a file
PipedWriter
used to write data to a pipe
CharArrayWriter
used to write data to a byte array
StringWriter
used to write string to a Writer
PrintWriter
used to print any data on Writer
BufferedWriter
provides buffer facility to the Writer
OutputStreamWriter
used to convert character stream to byte stream