Threads - Introduction

Threads - Introduction
Before going to concepts of threads, we need to understand the terminology of multitasking.

Task : Is an operation which is performed by the program or the application to provide expected results to the user.

Example: addition of two numbers in a calculator is a task.

Multitasking : Performing multiple tasks simultaneously is called multitasking.

There are two types of Multitasking
a. Process based Multitasking
b. Thread based Multitasking.

Process based Multitasking : Executing each tasks simultaneously where each task is an program or an application which is independent to each other.

Example : We can open IDE in your computer, we can play songs in the Computer, we can open the Messenger in the computer, so computer is doing multiple tasks, but each task is a independent application.

Process based multitasking we can widely see in Operating system level.

Thread based Multitasking : Executing each tasks simultaneously where each task is an independent part of the same application

Example : If you are doing an online transaction, you can see the same program will deduct the money from your account as well as you will receive the SMS or E-Mail of the successful transaction.

Thread based multitasking is best suitable at programmatic level.

The main objective of multitasking is to improve the response time of the application and give better performance of the system.

Threads in Java are very easy to implement when compared to the other legacy programming languages like C,C++ etc. because, Java by default provides rich multi threading API (Threads,Runnable,ThreadGroup).

Exception Handling - throws keyword

 Exception Handling - throws keyword
Throws :

We can handle exception handling by try/catch blocks or throws keywords.
If we want to handle the exception on the risky code within the same method then we will use try catch.

If we want to redirect to the caller to handle the exception which calls the method which can cause exception or Error, then the method which is called by the caller will be given throws keyword.

 Lets do a simple example on throws keyword.

package com.learning.test;
public class Test {

 public static void main(String[] args) {
  try {
   getNumber();
  } catch (Exception e) {
   System.out.println("Exception handled by the caller");
  }
  System.out.println("Addition : "+(10+10));
 }

 public static void getNumber() throws Exception{

  System.out.println(10 / 0);
 }
}


from the above class we can see, we are not handling the code in getNumber method instead we are throwing it
public static void getNumber() throws Exception {

We can see the main method which is the caller is calling the getNumber() method but we are handling it by try/catch.

                try {
   getNumber();
  } catch (Exception e) {
   System.out.println("Exception handled by the caller");
  }
Now lets run the class see the output

Output:
Exception handled by the caller
Addition : 20

we can run the code, the method getNumber() will raise an Arithmetic Exception which is a subclass of Exception, but it is handled by the caller. which is as below

a method can throw one or more exception types using throws keyword by comma separated values

public static void getNumber() throws ArithmeticException,IllegalStateException,......etc {

Where to use throws keyword?

throws keyword can be used at
a. method
b. constructor.

Note: We can use only throwable objects to throw exceptions using throws keyword.

Problems using the throws keywords:

 If the caller is not handling the exception which is cause by the called method, then the application will terminate immediately

Lets simulate it with a small example

package com.learning.test;

public class Test {

 public static void main(String[] args) {
 
  getNumber();
  System.out.println("Addition : "+(10+10));
 }

 public static void getNumber() throws ArithmeticException {

  System.out.println(10 / 0);
 }
}


In the above class, We are throwing Arithmetic Exception for getNumber().
public static void getNumber() throws ArithmeticException {
But the caller main method is calling getNumber() method but not handling the exception.

now lets run the class and see the output.

Output:
Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.learning.test.Test.getNumber(Test.java:13)
 at com.learning.test.Test.main(Test.java:7)

Since the main method didn't handle the code, Default exception handler handled the exception and JVM terminated the application.

Note: it is always recommended to use try/catch block instead of throws keyword, as throws keyword will not help in graceful termination of the application.

Exception Handling - throw keyword

Exception Handling - throw keyword
Throw Keyword

Before going to know about throw keyword we need to know how default exception handling takes place. We already know that if there is a run time exception and if its not handled then the default exception handler is responsible for handling the exception.

lets take a class which raises runtime exception
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  System.out.println(1000 / 0);
 }
}

We already know division by zero will raise ArithmeticException so the output is the following

Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:6)

So now we have question in our mind, who raised the arithmetic exception and how come the default exception handler know that it is Arithmetic Exception? the answer is in front us which is as below,
at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:6)
the method SampleClass.main raised exception.

So in java, methods are responsible for creating the the type of exception object and give it to the JVM, then JVM redirects to the default exception handler to handle the exception.

Now if you don't want method to create an exception object instead we want to create it explicitly then we will go for throw keyword.

lets take a class and lets raise an exception explicitly using throw keyword

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  throw new ArithmeticException("creating an exception object explicitly");
 }

}

output:
Exception in thread "main" java.lang.ArithmeticException: creating an exception object explicitly
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:6)

There are many real time requirements where we need to raise explicit exception object through throws key word.

For example: If you try to login to facebook without providing valid credentials, facebook won't  allow us to login and gives you the exception message, please provide valid credentials.

lets do a simple program which throws an exception if on providing wrong password.

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) throws Exception {
  String userName = "brkopensource";
  String password = "brk123";
  if (userName.equals("brkopensource") && password.equals("brk123")) {
   System.out.println("you have sucessfully Logged in");
  } else {
      throw new Exception("Invalid Credentials, Password should be brk123 but you have entered " + password);  }
 }

}

in the below, example in the if condition if we are checking the username and password is matched then the statement
System.out.println("you have sucessfully Logged in");
will be executed or we will explicitly throw the exception
throw new Exception("Invalid Credentials, Password should be brk123 but you have entered " + password);

lets run the code in two cases

case 1: valid credentials
i.e,  the values of user name and password are as below  

String userName = "brkopensource";
String password = "brk123";

Output:
you have sucessfully Logged in

case 2: invalid credentials,

String userName = "brkopensource";
String password = "brk1323";
Exception in thread "main" java.lang.Exception: Invalid Credentials, Password should be brk123 but you have entered brk3123
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:11)

since the if condition failed, we have explicitly raised an exception object of class java.lang.exception, with the description saying you entered wrong password.

Rules on using throw keyword:

1.  throws keyword can throw only throwable object. i.e, we can explicitly raise an object of the class only if its root class is java.lang.Throwable. We cannot throw objects of the class which is of the root java.lang.Object

lets take a class and lets try to use throw keyword for throwing an object which root class is Object class
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  throw new SampleClass();
 }
}

below code will give compile time error saying
No exception of type SampleClass can be thrown; an exception type must be a subclass of Throwable

lets take a class and lets try to use throw keyword for throwing an object where the root class is Throwable class

package com.learning.exceptionhandling;

public class SampleClass extends Exception {

 public static void main(String[] args) throws SampleClass {
  throw new SampleClass();
 }
}

In the above class i have extended the class with Exception class, Exception class is the child of Throwable class, So now if you run the code, it will execute successfully and throw the exception as below
Exception in thread "main" com.learning.exceptionhandling.SampleClass
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:6)

2. Since the program will be terminated when throw keyword encountered in the flow of execution of the code, so we cannot write statements next to throw statements.

package com.learning.exceptionhandling;

public class SampleClass extends Exception {

 public static void main(String[] args) throws SampleClass {
  throw new SampleClass();
  System.out.println("Hello World");
  System.out.println("I am bharani Ravi Kanth");

 }
}

from the above class the statements
System.out.println("Hello World");
System.out.println("I am bharani Ravi Kanth");
will never be executed, so we will get a compile time error saying "Unreachable code".

3. When we are throwing exception object, the object should be always initialized properly before throwing an exception, if we throw null reference of the exception object, throw keyword will throw NullPointerException

lets take a class and lets throw an exception will null reference

package com.learning.exceptionhandling;

public class SampleClass {

 static IllegalArgumentException illegal;

 public static void main(String[] args) throws IllegalArgumentException {
  throw illegal;
 }
}

In the above we created only the IllegalArgumentException static reference but didn't initialize it. and we already know by default the values of static is null. so if we throw IllegalArgumentException reference, we get the below output

Exception in thread "main" java.lang.NullPointerException
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:8)

lets take a class and lets throw an exception after initialization exception class object

package com.learning.exceptionhandling;

public class SampleClass {

 static IllegalArgumentException e=new IllegalArgumentException();

 public static void main(String[] args) throws IllegalArgumentException {
  throw e;
 }
}

In the above class we initialized the object for the  IllegalArgumentException class. we get the below output

 Exception in thread "main" java.lang.IllegalArgumentException
 at com.learning.exceptionhandling.SampleClass.(SampleClass.java:5)

Exception Handling - Finally Block.

Exception Handling - Finally Block.
Finally Block

Finally block is an additional block to the try/catch block. This block is used to maintain the clean up code and the  functionality of this block is, it executes irrespective of whether there is an exception or not.

lets do write a simple java class and see how finally block behaves.

Case1: Lets have try catch finally block, but the try block doesn't raise any exception.

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
  } catch (ArithmeticException e) {
   System.out.println("you are inside the catch block");
  } finally {
   System.out.println("you are inside finally block");
  }

 }

}

Lets run the code and see the output.

Output:
I am Bharani Ravi Kanth R
you are inside finally block

We can see the output, the risky code inside the try block didn't raise any exception, so catch block didn't activate, so immediately after the execution of the statements inside try block the control flows moves to finally block and started executing the statements inside the finally block.

Case2: Lets have try catch finally block, try block raises an exception of the type which catch block can handle.

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println(100/0);
  } catch (ArithmeticException e) {
   System.out.println("you are inside the catch block");
  } finally {
   System.out.println("you are inside finally block");
  }

 }

}

Lets run the code and see the output.

Output:
you are inside the catch block
you are inside finally block


We can see the output, the risky code inside the try block raised an ArithmeticException,So catch block got activated.After the execution of catch block statements, finally block is also executed.

Case3:  Lets have try catch finally block, try block raises an exception which is not of type, catch block can handle

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   String[] stringArray = null;
   System.out.println(stringArray[0]);
  } catch (ArithmeticException e) {
   System.out.println("you are inside the catch block");
  } finally {
   System.out.println("you are inside finally block");
  }

 }

}

Lets run the code and see the output.

Output:
Exception in thread "main" java.lang.NullPointerException
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:8)
you are inside finally block

We can see now, catch block couldn't handle the exception, so there was abnormal termination of the code, but before terminating finally block was executed.

We can conclude from case1, case and case3 that irrespective of no exceptions or handling the exceptions or not finally block will be always executed.

Finally block is majorly used when our program majorly deals with network. Best real time example we can give is When we are doing CRUD operations through database we have the close connections logic inside the finally block.

Rules of using Finally Block:
a. finally block can be used only if there is a try block. below are the valid syntax

Valid syntax 1:

try{
//risky code
}
catch(type of exception object){
}
finally{
}

Valid syntax 2: we can have try block with finally without catch.
try{
//risky code
}
finally{
}
Invalid case 1: there should be no statements between try catch and finally blocks, this will through compile time error.

try{
//risky code
}
catch(type of exception object){
}
System.out.println("statement 1")
finally{
}
Invalid case 2: there should be no statements between try  finally blocks, this will through compile time error.
try{
//risky code
}
System.out.println("statement 1")
finally{
}

b. Each try block can have only one finally block. i.e, below use of finally block is invalid

Invalid Syntax: 

try{
}
catch(type of exception object){
}
finally{
}
finally{
}

Invalid Syntax: 

try{
}
finally{}
finally{
}

if you more than one finally block you will get compile time error.

Exception Handling - Customized Exception Handling using Try/Catch

Exception Handling - Customized Exception Handling using Try/Catch
In case of an runtime exception, exception arises in the application if we didn't handle the code, 
Handling the unhandled exception which is raised by the application is done by the JVM through its default exception handler. The problem with the default exception handling is, it abnormally terminates the application. which is not a good practice.

For example, lets take simple java class which causes abnormal termination.
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  System.out.println("I am Bharani Ravi Kanth R");
  System.out.println("My age is  " + 54 / 0);
  System.out.println("I am a DevOp");
 }
}

lets run this code.

Output:

I am Bharani Ravi Kanth R
Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:8)

You can see the application terminated abnormally.
System.out.println("My age is  " + 54 / 0);
the above line of code caused the issue and terminated immediately and the remaining code is never  executed.

So, that's why we need to handle the code for graceful termination of the code,

Before handling the code first we need to know what is Risky Code.
The line of code which causes exception is called risky code.  In the above example the line
System.out.println("My age is  " + 54 / 0);
is said to be risky code.

lets try with the above example handle the code using try catch, risky code should be inside try block and if an exception is caused, the handled code should be inside catch block. which is as below.
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {

  System.out.println("I am Bharani Ravi Kanth R");
  try {
   System.out.println("My age is  " + 54 / 0);
  } catch (ArithmeticException e) {
   System.out.println("My age is  " + 54 / 2);
  }
  System.out.println("I am a DevOp");
 }
}

In the above class :

Risky code,
System.out.println("My age is  " + 54 / 0);

Catch block:  Type of Exception which can be caused by Risky Code  is ArthmeticException, catching the exception of type ArthmeticException, Which is nothing but the catch block is activated only if there is an arthmetic exception.

Handled code:
System.out.println("My age is  " + 54 / 2);

Lets run the class.

Output:
I am Bharani Ravi Kanth R
My age is  27
I am a DevOp

You can see the now handled code is executed, and rest of the statements of the class are also executed without any abnormal termination.


Control Flow of try/catch Block:

when an exception is handled, in what order the statements in the application are executed can be seen in this control flow.

Lets see all the cases programmatically.

Case 1: If there is no exception raised by the risky code.
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
   System.out.println("My age is  " + 27);
   System.out.println("I Love Linux");
  } catch (ArithmeticException e) {
   System.out.println("My age is  " + 54 / 2);
  }
  System.out.println("I am a DevOp");
 }
}

in the above class, in the try block the risky code will  raise no exception in the run time, if there no exception then catch block will be not activated, the flow of execution would the lines inside of the risky code and the line of code which is after catch block.

lets run and see the code.

Output:
I am Bharani Ravi Kanth R
My age is  27
I Love Linux
I am a DevOp

Case 2: If there is an exception raised by the risky code, and catch block catching the same exception type
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
   System.out.println("My age is  " + 27/0);
   System.out.println("I Love Linux");
  } catch (ArithmeticException e) {
   System.out.println("My age is  " + 54 / 2);
  }
  System.out.println("I am a DevOp");
 }
}

In the above class we can see that exception would be raised at the line
System.out.println("My age is  " + 27/0);
and type of the exception is raised is ArithmeticException, and catch block is matching it and handled code will be executed. so now the order of execution will be

1. Statement 1 will be executed which is below line of code, 
System.out.println("I am Bharani Ravi Kanth R");

2. While executing the statement 2,
System.out.println("My age is  " + 27/0);
An exception of type ArithmeticExcepion is raised and catch block is activated and the statement inside the catch block which is below will be executed.
System.out.println("My age is  " + 54 / 2);
3 Next execution control goes to the statement which is immediately outside the catch block. the statement
System.out.println("I am a DevOp");

4)The statement
System.out.println("I Lovee Linux");
will never be executed because, once the the control moves from try to catch the remaining statements after the statement which raised the issue will never be executed

Lets run the code,

Output:
I am Bharani Ravi Kanth R
My age is  27
I am a DevOp

you can see from the output  the statement below is completely ignored
System.out.println("I Love Linux");

Note: Its a good practice having the statements only the risky code inside the try block, so that the non risky code inside the try block will not be ignored after an exception  is raised. 


Case 3: If there is an exception raised by the risky code, and catch block is not handling the type of exception raised.
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
   int[] ageArray = null;
   System.out.println("My age is  " + ageArray[0]);
   System.out.println("I Love Linux");
  } catch (ArithmeticException e) {
   System.out.println("My age is  " + 54 / 2);
  }
  System.out.println("I am a DevOp");
 }
}

In the above class, we can see the exception will raise at the statement below
System.out.println("My age is  " + ageArray[0]);
We trying to access an index of null array, so it will for sure raise NullPointerException.But the catch block is not handling NullPointerException but handling only ArithmeticException so in this the application will abnormally terminate when the exception is raised.

In the below case, only statement 1 which is below will be executed
System.out.println("I am Bharani Ravi Kanth R");
and then program will be terminated

Lets run the code,

Output:
I am Bharani Ravi Kanth R
Exception in thread "main" java.lang.NullPointerException
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:9)

Case 4: If there is an exception raised by the risky code, and catch block catching the same exception type, but the handled code turned out to be risky.
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
   System.out.println("My age is  " + 27 / 0);
   System.out.println("I Love Linux");
  } catch (ArithmeticException e) {
   System.out.println("My age is  " + 54 / 0);
  }
  System.out.println("I am a DevOp");
 }
}

In the above class, we can see the exception will raise at the statement below
System.out.println("My age is  " + 27 / 0);
The exception type is ArithmeticException and catch block is activated once the exception is raised but catch block is also having risky code which raises exception.
System.out.println("My age is  " + 54 / 0);
even the above statement will raise ArithmeticException. even in this case the code abnormally terminates when the statement in the catch block is executed.

In the below case, only statement 1 which is below will be executed
System.out.println("I am Bharani Ravi Kanth R");
and then program will be terminated

Lets run the code,

Output:

I am Bharani Ravi Kanth R
Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:11)


Below are the control flow cases, so use the try/catch block smartly and keep the try block as small as possible.


Methods to print exception Information:

There are three methods where we can print the exception information,
1. printStackTrace()
2. getMessage()
3. toString()


Printing exception information by printStackTrace():
 If an exception is raised and if we want to print the exception details, Like Name of the Exception, cause of the exception, also the which line of code the exception is raised.  Then we have to go for printStackTrace() method

Lets take a simple class and print the exception when an exception is raised.

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
   System.out.println("My age is  " + 27 / 0);
   System.out.println("I Love Linux");
  } catch (ArithmeticException e) {
   e.printStackTrace();
  }
 }
}

Output :

I am Bharani Ravi Kanth R
java.lang.ArithmeticException: / by zero
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:8)

we can see  the output printStackTrace() method is printing the following

1. Name of the Exception 
java.lang.ArithmeticException
2. Reason for the exception
: / by zero
3. At what point the code the exception is raised
at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:8)

Printing exception information by exception object reference or toString() Method:

 If an exception is raised and if we want to print the exception details, Like Name of the Exception, and cause of the exception and doesn't want to show in what point the exception is raised, then we will print the object reference or explicitly toString() Method of that exception object, if we are printing an object reference internally toString() method is called.

Lets take a simple class and print the exception with the exception object reference and toString method()

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
   System.out.println("My age is  " + 27 / 0);
   System.out.println("I Love Linux");
  } catch (ArithmeticException e) {
   System.out.println(e);
   System.out.println(e.toString());
   
  }
 }
}

Output:
I am Bharani Ravi Kanth R
java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero

We can see the output  for printing the  exception object reference or toString() method.

1. Name of the exception
java.lang.ArithmeticException
2. Reason for the exception
: / by zero


Printing exception information using getMessage() Method:
 If an exception is raised and if we want to print the exception details, only reason of the exception,  Then we have to go for getMessage() method

Lets take a simple class and print the exception using getMessage() method.

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
   System.out.println("My age is  " + 27 / 0);
   System.out.println("I Love Linux");
  } catch (ArithmeticException e) {
   System.out.println(e.getMessage());
   
  }
 }
}

Output:
I am Bharani Ravi Kanth R
/ by zero

We can see the output of getMessage() method above.

 Reason for the exception for the exception only printed.
/ by zero


Note: 
1. printStackTrace(),toString() and getMessage() can be used in any exception or error object as these are the methods of its root class Throwable.
2. printStackTrace() method will print the exception in the console.


try with multiple catch blocks:

We see in most of the cases, programmers use the following way to handle an exception as below

try
{
//risky code
}
catch(Exception e)
{
 //handle exception logic
}

Below format works but if we want to have  different handle code logic on different exceptions then
 using catch block as below is not valid.

catch(Exception e)
{
 //handle exception logic
}  

lets take a sample java class and will see how multiple catch blocks works.


package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {
  try {
   System.out.println("I am Bharani Ravi Kanth R");
   System.out.println("My age is  " + 27 / 0);
  } catch (NullPointerException e) {
   System.out.println("This is null pointer exception catch block : "+e.getMessage());

  } catch (ArithmeticException e) {
   System.out.println("This is Arithmetic exception catch block : "+e.getMessage());
  }

 }
}

We can see in different blocks we are performing different tasks, Now when we run the code and exception is raised, JVM picks the exception checks the catch block from top to bottom whether that catch block can handle the exception.

In the present example type of exception raised is ArithmeticException, when the exception is raised the controls goes to the first catch block, but the current catch block can handle only null pointer exception, Now the control comes out and checks the other catch block,Now the second catch block can catch ArithmeticException, the second catch block will be activated and run the executes the statements which is inside that catch block. 

Lets run the code.

Output:

I am Bharani Ravi Kanth R
This is Arithmetic exception catch block : / by zero


Rules of multiple catch block is:

1. Order of the catch block should be mandatory, i.e, first child classes of exceptions are used then the parent class and not the vice versa.

for example, below is the valid example

try
{
Risky Code
}
catch(NullPointerException e)
{
}
catch(Exception e)
{
}

below is not valid, because parent class Exception can handle even NullPointerException, So the null pointer exception catch block is never called.

try
{
Risky Code
}
catch(Exception e)
{
}
catch(NullPointerException e)
{
}

2. There cannot be two catch blocks with same exceptions type.

try
{
Risky Code
}
catch(NullPointerException e)
{
}
catch(NullPointerException e)
{
}

above usage of is not valid because, once the NullPointerException catch block is executed the control moves out the catch area, so the next block will be never called.



Exception Handling - Checked Vs Unchecked Exceptions

Exception Handling - Checked Vs Unchecked Exceptions
There are two types of Exceptions

1. Checked Exceptions
2. Unchecked Exceptions

Checked Exceptions : These are the type of exceptions which are raised by the compiler for smooth execution of the code in the run time.

Lets take a simple real time scenario between Mother,Son and Lunch Box.

1. When the child is leaving to school, Mother asks the Son whether he has taken the lunch box with him,
 2. Son Checks his bag and tell his mother that he has taken the lunch box.

Here, The mother is checking the child because, if the he forget his lunch box, he would miss the meal at the lunch break.

If we represent it in java.

Mother - Java Compiler.
Student - Is the application.
Lunch Box - Is the parameter checked by the compiler, which may cause an issue.

Lets do a simple example, for Better understanding do not use an IDE for this example. 
package com.learning.exceptionhandling;

import java.io.PrintWriter;

public class SampleClass {

 public static void main(String[] args) {
  PrintWriter printWriter=new PrintWriter("c:/Sample.txt");
  printWriter.write("I am Bharani Ravi Kanth R");
 }
}

I am trying to print a text "I am Bharani Ravi Kanth R" to a file called Sample.txt. lets try compiling the code through command line.

C:\com\learning\exceptionhandling>javac SampleClass.java
SampleClass.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
                PrintWriter printWriter=new PrintWriter("c:/Sample.txt");
                                        ^
1 error

Here its not an issue with the application, but compiler is helping us to be cautious, What if the file you are trying to access doesn't exist at all. So the compiler is giving us the below message

unreported exception FileNotFoundException; must be caught or declared to be thrown
i.e, handle the code if the file we are trying to access doesn't exist.

There are two ways we can handle the checked exceptions,
1. try catch block.
2. throws keyword.

So in the above example, we can handle the code as below so that compiler compiles our code properly.

try catch block:

package com.learning.exceptionhandling;

import java.io.FileNotFoundException;
import java.io.PrintWriter;

public class SampleClass {

 public static void main(String[] args) {
  try {
   PrintWriter printWriter = new PrintWriter("c:/Sample.txt");
   printWriter.write("I am Bharani Ravi Kanth R");
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  }
 }
}

throws keyword:

package com.learning.exceptionhandling;

import java.io.FileNotFoundException;
import java.io.PrintWriter;

public class SampleClass {

 public static void main(String[] args) throws FileNotFoundException {
   PrintWriter printWriter = new PrintWriter("c:/Sample.txt");
   printWriter.write("I am Bharani Ravi Kanth R");
 }
}

Now let us compile the code.

C:\com\learning\exceptionhandling>javac SampleClass.java

C:\com\learning\exceptionhandling>

We can see now that compiler has no issues compiling the code.

Checked Exceptions are checked in two ways

1. Fully Checked: We need to check both parent and child,
2. Partial Checked: If we check only the parent not its child classes.


Note: Only possible partial checked exceptions classes in java are Throwable and Exception.


Unchecked Exceptions: The exceptions which are caused by the application, mostly at runtime,
Unchecked Exceptions are mostly

1. Errors
2. Runtime Exceptions.

Unchecked Exceptions - Error:  we are trying to run the application in the server, but the application couldn't start up because of OutOfMemory error, that is application is not having enough heap space to run. here its not the application which caused the issue, but the server doesn't have enough system resources to run the application.

Unchecked Exceptions - Runtime Exceptions: These are the exceptions which are caused by the applications at runtime, like dividing an integer by zero this causes ArithmeticException, trying to access an object which was never initialized causes null pointer exception.


Lets see a simple example, we are trying to fetch an value from an string array object which never initialized

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {

  String[] stringArray=null;
  System.out.println(stringArray[0]);
 }
}

Output:
Exception in thread "main" java.lang.NullPointerException
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:8)


Note: Runtime exceptions are not found by the compiler while compiling our source code.


Exception Handling - Exception Hierarchy

Exception Handling - Exception Hierarchy
The Root of all the Exception and Errors in java is Throwable class.

Please note: "Throwable is a class not an Interface."

Throwable has two sub Classes

1. Exception
2. Error

Exception : Mostly Exceptions are caused by the our program, For example

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String[] args) {

  String[] stringArray = new String[9];
  for (int i = 0; i < 10; i++) {
   stringArray[i] = "It has the value : " + i;
                        System.out.println("It has the value : " + i);
  }

 }
}

Output:

It has the value : 0
It has the value : 1
It has the value : 2
It has the value : 3
It has the value : 4
It has the value : 5
It has the value : 6
It has the value : 7
It has the value : 8
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:10)


In the below class we have taken an array of size 9, now we try to access the 10th block in that array our application thrown an exception.

Exceptions can be recovered  by handling the code so that rest of the flow of the application can continue.

Error : These type of issues are not caused by the application which we built, it occurs due to in sufficient system resources available to run the application that we built. Errors are not recoverable we have to just to terminate the application.

Best example for an Error is OutOfMemory Error, this caused when the application is not having enough heap.

 Exceptions has many Sub Classes, but below are the major sub classes of Exception.

1. Runtime Exceptions 
            a. NullPointerException
            b. ArithmeticException
            c. ClassCastException.
            d. IndexOutOfBoundException.
            e. IllegalArgumentException
            
2. Io Exceptions
       a. FileNotFoundException
       b. EOFException
       c. InterruptedIOException.
3. Remote Exceptions
4. Interrupted Exceptions
5. Servlet Exception.


Error has Sub Classes as below

1. Vm Error: In Vm Error we see mostly two common errors
                a. StackOverFlow Error
                b. OutOfMemory Error
2. Assertion Error
3. ExceptionInInitializer Error.


Exception Handling - Default Exception Handling

Exception Handling - Default Exception Handling
Before going to the definition, we will see a small example of  a routine of a school student.
Lets say if the school starts at 9 am.

1. Student has to wake up in the morning at 6:30 AM
2. Student has to take breakfast at 7:30 AM
3. Student has to take the school bus at 8 AM
4. Student will reach the school at 8:30 AM, attends the school prayer and will go to the class and start listening to lectures.

Now in a weekday unexpectedly student suffered from fever and the doctor advises the student to take rest, now the entire routine like waking up in the morning, having breakfast, going to school and listening lectures got disturbed. What is here the unexpected event? Student felling sick, this is an exception.

What is an Exception ? 

An unwanted or unexpected event which disturbs the entire flow of the application.


Why to handle Exceptions?

It is highly recommended to handle the exceptions, the main objective of exceptional handling is "graceful termination of the program" or handle the program in such a way that rest of the program will be executed.


Default Exception Handling in Java

Before going to Default Exception Handling we not to know, what is Runtime Stack Mechanism, 

What is Runtime Stack?

JVM creates a stack in the stack area, in which the list of methods to be executed by a thread at the runtime.

For each Thread, a new runtime stack is created.

what is Runtime Stack Mechanism? 

When a thread is executed, run time stack is created.
After successful execution, JVM checks each stack frame in the stack, whether the method is executed is successfully, its checks by one by one and removes the entry the from the stack. once all the entries are removed, the empty is stack is destroyed by JVM.

This complete process is called Runtime Stack Mechanism
Lets represent it programmatically
package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String... args) {
  callfirstMethod();
 }

 public static void callfirstMethod() {
  callSecondMethod();
 }

 public static void callSecondMethod() {
  printTheName();
 }

 public static void printTheName() {
  System.out.println("Bharani Ravi Kanth R");
 }

}

When we run this code, here the code starts from main method so, thread name by default given to as main thread.

first an JVM creates an empty stack, then it provides the list of "stack frames" which are to be executed by the Thread.


 -----------------------------
|                             |
 -----------------------------
  Runtime Stack


main thread will start executing from main method, thread makes an entry of main method in the stack.


 -----------------------------
|        main()               |
 -----------------------------
    Runtime Stack

Now the list of methods calls which are to be done will be entered.

 -----------------------------
|  printTheName()            |
 -----------------------------
|  callsecondMethod()        |
 -----------------------------
|  callfirstMethod()         |
 -----------------------------
|  main()                    |
 -----------------------------
  Runtime Stack


Now, after the execution of all the methods are successful by the thread, JVM will remove the stack frames one by one from the Stack. Since its a stack, Last in record will be removed first, PrintTheName() will be removed first and main() method is removed. After the Removal of all the stack frames, JVM will destroy the stack.

Now we will see what Default Exception Handling. lets create a class SampleClass.java

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String... args) {
  callfirstMethod();
 }

 public static void callfirstMethod() {
  callSecondMethod();
 }

 public static void callSecondMethod() {
  calculate();
 }

 public static void calculate() {
  System.out.println(1/0);
 }
}

We already know 1/0 application will throw an exception, but the below code we didn't handle the exception, so it will be JVM's hand to handle the exception.

 When we run the code,
1. JVM first creates the empty runtime stack in the stack area,
2. JVM will enter the stack frames (information regarding the method call) into the stack as below


 -----------------------------
|  calculate()               |
 -----------------------------
|  callsecondMethod()        |
 -----------------------------
|  callfirstMethod()         |
 -----------------------------
|  main()                    |
 -----------------------------
  Runtime Stack

when the thread "main" starts executing the code, starts from main()->callfirstMethod()->callSecondMethod()->calculate(),

now the calculate method will throw the exception because we trying to print the value 1/0,

Now lets see how JVM handles the situation,

1. when the exception is triggered, JVM goes to the calculate method, checks for the calculate method has handled the exception or not. Calculate method has no handling of exception.

2.  Now JVM goes to the method which called calculate() method, i.e, callsecondMethod() method, and checks here whether this method has handled the exception, callsecondMethod() method didn't handle the execption,

3. Now JVM goes to the method which called callsecondMethod() method, i.e, callfirstMethod() method and checks here whether this method has handled the exception or not,callfirstMethod() method handle the exception.

4. Now JVM goes to the main method has handled the exception since it called callfirstMethod() method,

5. Since none of the methods handled the exception now its JVM turns to handle it, So JVM calls its "Default Exception Handler" to handle the current situation of the code, this exception handler will forcefully stop the application, and print the trace of the runtime stack or also called as StackTrace which is recorded by the JVM from the starting point of the exception to the method where the actual flow started, once the stack trace is printed JVM destroys the stack.

Default Exception Handler will print stacktrace  as below for format:

Exception in thread "name of the thread" ExceptionClass(with package) : Exception caused by description
          at  ClassName(with package).method (StartingPointOftheExceptionClassName.java:lineNumber of the exception)
          at  ClassName(with package).method (ClassName.java:line number of the code inside the method caused the exception)
          at  ClassName(with package).method (ClassName.java:line number of the code inside the method caused the exception)
          .
          .
          .
          .
          .
         FlowStartedClass(with package).method(FlowStartedClass.java:line number of the code inside the method caused the exception)

Lets the above example SampleClass.java

package com.learning.exceptionhandling;

public class SampleClass {

 public static void main(String... args) {
  callfirstMethod();
 }

 public static void callfirstMethod() {
  callSecondMethod();
 }

 public static void callSecondMethod() {
  calculate();
 }

 public static void calculate() {
  System.out.println(1/0);
 }
}

If we execute the code, Default Exception Handler will handle the situation and prints the below stacktrace.

Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.learning.exceptionhandling.SampleClass.calculate(SampleClass.java:18)
 at com.learning.exceptionhandling.SampleClass.callSecondMethod(SampleClass.java:14)
 at com.learning.exceptionhandling.SampleClass.callfirstMethod(SampleClass.java:10)
 at com.learning.exceptionhandling.SampleClass.main(SampleClass.java:6)


1. "main" is the thread name
2. "java.lang.ArithmeticException" Type of Exception, its class name with package,
3. "/ by zero" reason for the exception.
4. "com.learning.exceptionhandling.SampleClass.calculate" is the where the execption occured.
5. "(SampleClass.java:18)" is at the line number thrown the exception.
6. "com.learning.exceptionhandling.SampleClass.main" is where the flow has started"

OOP - Data Abstraction - Interfaces

OOP - Data Abstraction - Interfaces
What is an Interface?

An Interface is a reference type in Java (Note: we will discuss more about primitive and reference type in the upcoming blogs). An Interface is blueprint to a class and it contains collections of static variables and abstract methods. An interface will never have concrete methods.

In other words, when we talk about interface we are providing the contract what can the object do.

Interface is defined with the interface keyword, below is the simple example how an interface is defined.

package com.learning.interfaces;

public interface SampleInterface {
 void getMethod1();
 int getMethod2();
}

if you observe here
void getMethod1();
int getMethod2();

I didn't give any modifiers and abstract keyword, but in an interface all the defined methods are by default abstract and public and the constants used are static, as like abstract classes even interfaces cannot be instantiated.

Since it is said that interface provides the capabilities what an Object can do,  We will do a simple POC on this. We will take a real time example of an ATM machine.

Lets create an interface ATMInterface.java

package com.learning.interfaces;

public interface ATMInterface {

 String getBalance(String username, String Passwords);

 void updateBalance(String username, String Passwords);

 void moneyDeposit(String username, String Passwords);

 void changeLanguage(String username, String Passwords);

 void changePin(String username, String Passwords);
}

we use implements keyword to inherit an interface to a class.

Now the class which is implementing the ATM interface, should by default implement all the defined methods in the interface,

package com.learning.interfaces;

public class ATMClientClass implements ATMInterface {

 @Override
 public String getBalance(String username, String Passwords) {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public void updateBalance(String username, String Passwords) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public void moneyDeposit(String username, String Passwords) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public void changeLanguage(String username, String Passwords) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public void changePin(String username, String Passwords) {
  // TODO Auto-generated method stub
  
 }
}

We can see the ATMClientClass.java when implemented  all the abstract methods of the interface should be implemented in the class.

We cannot have a multiple inheritance between classes but we can achieve multiple inheritance using interfaces, a class can implement one or more interfaces.

Will do a simple POC how it is done, lets take two interface which has two abstract methods each

Inteface1.java
package com.learning.interfaces;

public interface Interface1 {

 void getMethod1OfInterface1();

 void getMethod2OfInterface1();

}

Interface2.java

package com.learning.interfaces;

public interface Interface2 {

 void getMethod1OfInterface2();

 void getMethod2OfInterface2();
}


Now lets implements these two interfaces, to a class MultipleInterfaceClass.java
package com.learning.interfaces;

public class MultipleInterfaceClass implements Interface1,Interface2{

 @Override
 public void getMethod1OfInterface2() {
 }

 @Override
 public void getMethod2OfInterface2() {
  
 }

 @Override
 public void getMethod1OfInterface1() {
  
 }

 @Override
 public void getMethod2OfInterface1() {
  
 }
}

Now here you can see the class now should implement all the abstract methods of both the interfaces.

Can we implement an interface to an Abstract class?

Yes we can implement but the abstract methods in the interface for sure to be implemented in the abstract class. 


package com.learning.interfaces;

public abstract class SampleAbstractClass implements Interface1 {

 @Override
 public void getMethod1OfInterface1() {

 }

 @Override
 public void getMethod2OfInterface1() {

 }

 public abstract void getSampleAbstractClass();

}




OOP - Data Abstraction - Abstract Classes

OOP - Data Abstraction - Abstract Classes
Data Abstraction is one of the concept of Object Oriented Java Programming, By Data Abstraction we can able to show the services provided by the application to the outside by hiding the internal implementation.
For Example, If you go to Facebook, We chat, We post stuff in the timelines, We like, We share the posts. all these are services provided by the Facebook, but Facebook is hiding the background implementation to the end user. (i.e, what code it is executing if we click on like button, what code is executing we share etc).


In Java, Abstraction can be done in two ways.

1. Abstract Classes (Partial abstraction).
2. Interfaces (complete abstraction).

Abstract Classes : In Java when a class is declared with keyword abstarct then class is declared as an abstract class.

If a class is having at least on abstract method then for sure class will be abstract, that is we have only method defined but not implemented.


Sample Abstract class is as below.

package com.learning.partialAbstraction;

public abstract class SampleAbstractClass {
 public void getSampleMethodwithReturnVoid() {
  System.out.println("Sample Abstract Class");
 }
 abstract void getSampleAbstractMethod();
}

From the above class,
abstract void getSampleAbstractMethod();

is the abstract method as there is no method implimentation, and the abstract class can also contain concrete method
public void getSampleMethodwithReturnVoid() {
  System.out.println("Sample Abstract Class");
 }

 We can also declare instance variable to  be public,privatc, static, final  etc, there are no restrictions on using access modifiers on instance variables in the abstract class,

but abstract methods cannot be final,static and private because, implementation logic of the abstract method should be done by its sub classes,Most  importantly you cannot instantiate an abstract class.

abstract methods can have three levels of access modifiers,
1. no access modifier (will be treated as default) -- only (abstract can be extended by the classes of same package.
2. public - you have universal access of this abstract.
3. protected -  classes of the same package and outside package of same work space.
 

Why Abstract Classes? this is the question which is asked by many.
 Abstract Classes are introduced because, if your not sure of the complete requirement.




In other words, when we talk about abstract classes, we talk about how an object behaves, we are providing the characteristics of the object type.

 For example: Lets take an example of a Man (note:Its not gender biasing on women :))

1. A Man has to Sleep, Its a common feature,
2. A Man has to Work, But we are not sure what kind of work,

so the common feature will be the concrete method, the working feature we are not sure, so we are making it Abstract.
  Below is the representation of the example.

package com.learning.partialAbstraction;

public abstract class AbstractManClass {

 public String sleepMethod() {
  return "on an average a man sleeps for 8 hours";
 }
 public abstract String typeOfWork();
}

there are different type  of work a man can do. lets see how the abstract classes are extended and implement the abstract typeOfWork() method.

Lets take two classes ManA.java and ManB.java

package com.learning.partialAbstraction;

public class ManA extends AbstractManClass{
 public String typeOfWork() {
  return "Is a JAVA PROGRAMMER";
 }
}


package com.learning.partialAbstraction;

public class ManB extends AbstractManClass {
 public String typeOfWork() {
  return "Is a TESTER";
 }
}


Now lets the classes,


package com.learning.partialAbstraction;

public class TestingAbstractClass {

 public static void main(String[] args) {
  ManA a = new ManA();
  System.out.println("------------------------------------");
  System.out.println("Man A " + a.sleepMethod());
  System.out.println("Man A " + a.typeOfWork());
  ManB b = new ManB();
  System.out.println("------------------------------------");
  System.out.println("Man B " + b.sleepMethod());
  System.out.println("Man B " + b.typeOfWork());
  System.out.println("------------------------------------");
 }
}

Output:
------------------------------------
Man A on an average sleeps for 8 hours
Man A Is a JAVA PROGRAMMER
------------------------------------
Man B on an average sleeps for 8 hours
Man B Is a TESTER
------------------------------------

So in the above example we can see, there two different Man classes, both the classes has one common thing which is sleep,  and the other work is different. 

One more interesting topic of abstract classes are the,
Generic Abstract Classes, if we want to enforce the return type of the abstract method, we go for generic abstract type.

Lets create an Abstract class GenericAbstractClass.java

package com.learning.inheritance;

public abstract class GenericAbstractClass<Type> {
 public abstract Type abstractMethod();
}

Here Type may be return type, so when we extend this class, We have to pass the Return type while extending, such that the implemented method strictly follows the same return type.

Lets take a class Subclass.java extending the GenericAbstractClass

package com.learning.inheritance;

public class SubClass extends GenericAbstractClass<Void>{
 @Override
 public Void abstractMethod() {
  return null;
 }
}


Void here is not a keyword, its a class available in java.lang. package, which returns a value null. as in Generics keywords are not accepted.

example for Ineteger gereric type

package com.learning.inheritance;

public class SubClass extends GenericAbstractClass<Integer>{
 @Override
 public Integer abstractMethod() {
  return null;
 }
}

These Generic Abstract classes widely used in the Command Pattern (will discuss more on this pattern when we cover design patterns).

Java Inheritance

Java Inheritance
Inheritance is a mechanism in java which makes the properties of a class available to it subs classes.

Why Inheritance?

1. We can modify the existing implementation of a class in your sub class, in technical terms ro achieve run time Polymorphism. (Method overriding).

2. Code Re-usability.

How many Inheritance does java supports?

There are three kinds of inheritances supported in java.

1. Single inheritance.
2. Multilevel inheritance
3. Hierarchical inheritance. 

Inheritance in Java has two subtopics

1. Is-A Relationship
2. Has-A Relationship.

Is-A RelationShip :

Is-A Relationship is concept of providing, the properties of a class inherited another class. this can be done using extends keyword.

Lets do a simple POC on this concept. Lets create a parent class  ParentClass.java

package com.learning.inheritance;
public class ParentClass {
 public String getName() {
  return "My Name is Ravi kanth";
 }
}

Now lets extend the parent class to a class ChildClass.java and lets try to access getName() of the parent class in child class.


package com.learning.inheritance;

public class ChildClass extends ParentClass {
 public static void main(String[] args) {
  ChildClass childClass = new ChildClass();
  System.out.println(childClass.getName());
 }
}


Lets run the ChildClass.java and see the output

Output:

My Name is Ravi Kanth


You can clearly see the output, that child class object can use parents properties.

Now lets create a method which same and return type in ChildClass.java


package com.learning.inheritance;

public class ChildClass extends ParentClass {
 public static void main(String[] args) {
  ChildClass childClass = new ChildClass();
  System.out.println(childClass.getName());
 }

 public String getName() {
  return "My Name is John";
 }
}


Lets run the ChildClass.java and see the result:

Output:

My Name is John


you can see the it is printing the method of the childClass but not parent class, so you are overriding the methods of the parent class. This is called Method Overriding.

Points to be noted in a Is-A  Relationship.

1. By default all the Public and protected properties of the parent class is available to the sub classes.
2. We can always override the methods which are provided by the parent class to the subclasses until and unless if the methods are not declared as final
3.  You can hold parents reference in the child Object.


Has-A Relationship :

If a class have entity relationship of another class is called Aggregation or Composition. So Aggregation in java represents the Has-A relationship.

Lets do a simple POC on this concept.

Lets create a employee class Employee.java


package com.learning.inheritance;

public class Employee {
 
 private String firstName;
 private String lastName;
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 } 
}

But Employee information is incomplete, Employee working in a company has may other parameters like Employee Address, Employee Bank Details.

I have already  two classes which holds that information, which is as below.
  
EmployeeAddressInformation.java

package com.learning.inheritance;

public class EmployeeAddressInformation {

 private String houseNumber;
 private String streetName;
 private String city;
 private String state;
 private String country;
 private String pinCode;

 public String getHouseNumber() {
  return houseNumber;
 }

 public void setHouseNumber(String houseNumber) {
  this.houseNumber = houseNumber;
 }

 public String getStreetName() {
  return streetName;
 }

 public void setStreetName(String streetName) {
  this.streetName = streetName;
 }

 public String getCity() {
  return city;
 }

 public void setCity(String city) {
  this.city = city;
 }

 public String getState() {
  return state;
 }

 public void setState(String state) {
  this.state = state;
 }

 public String getCountry() {
  return country;
 }

 public void setCountry(String country) {
  this.country = country;
 }

 public String getPinCode() {
  return pinCode;
 }

 public void setPinCode(String pinCode) {
  this.pinCode = pinCode;
 }

}

EmployeeBankInformation.java


package com.learning.inheritance;

public class EmployeeBankInformation {

 private String bankName;
 private String employeeNameinBankAccount;
 private String bankAccountNo;
 private String bankAddress;
 private String bankBranch;
 private String bankIfscNumber;

 public String getBankName() {
  return bankName;
 }

 public void setBankName(String bankName) {
  this.bankName = bankName;
 }

 public String getEmployeeNameinBankAccount() {
  return employeeNameinBankAccount;
 }

 public void setEmployeeNameinBankAccount(String employeeNameinBankAccount) {
  this.employeeNameinBankAccount = employeeNameinBankAccount;
 }

 public String getBankAccountNo() {
  return bankAccountNo;
 }

 public void setBankAccountNo(String bankAccountNo) {
  this.bankAccountNo = bankAccountNo;
 }

 public String getBankAddress() {
  return bankAddress;
 }

 public void setBankAddress(String bankAddress) {
  this.bankAddress = bankAddress;
 }

 public String getBankBranch() {
  return bankBranch;
 }

 public void setBankBranch(String bankBranch) {
  this.bankBranch = bankBranch;
 }

 public String getBankIfscNumber() {
  return bankIfscNumber;
 }

 public void setBankIfscNumber(String bankIfscNumber) {
  this.bankIfscNumber = bankIfscNumber;
 }

}

In the Employee Class. Instead of again adding the parameters which holds the details of the employee information, we can use the existing classes references  in your Employee class.  which is below.

package com.learning.inheritance;

public class Employee {

 private String firstName;
 private String lastName;
 private EmployeeAddressInformation addressInformation;
 private EmployeeBankInformation employeeBankInformation;

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public EmployeeAddressInformation getAddressInformation() {
  return addressInformation;
 }

 public void setAddressInformation(EmployeeAddressInformation addressInformation) {
  this.addressInformation = addressInformation;
 }

 public EmployeeBankInformation getEmployeeBankInformation() {
  return employeeBankInformation;
 }

 public void setEmployeeBankInformation(EmployeeBankInformation employeeBankInformation) {
  this.employeeBankInformation = employeeBankInformation;
 }

}

Now Employee Class Has -A Relationship with EmployeeAddressInformation and EmployeeBankInformation classes.

The Major Advantage of Has-A Relationship is code re-usablility.