Pages

Tuesday 17 September 2019

Exception handling

Agenda
  • Exception
  • Exception Handling
  • Benefits of Exception Handling
  • Hierarchy of Exception
  • Keywords related to exception
  • Default exception handling in java
  • The possible combination of try, catch and finally
  • Multi-catch block
  • Try-with resources
  • Custom Exception
  • Assertions
Exception
An event that disturbs the normal flow of the program is called an exception.
Examples:
NullPointerException
ArrayIndexOutOfBoundException
FileNotFoundException
IOException
If an exception raised at any particular line, then the program will terminate abnormally. This means the remaining lines of the program will not be executed.

Q. How can you stop abnormal termination of the program?
Ans: Exception Handling mechanism, using keywords try, catch.

Exception Handling
Put the risky codes inside a try block and handle it in the catch block.
Risky codes are those which cause the abnormal termination of the program.
Example:
  1. public class Test {
  2. public static void print() {
  3. int a=10;
  4. int b=0;
  5. System.out.println(a/b);// This is risky  code, cause it will throw ArithmeticException         
  6. }
  7. public static void main(String[] args) {
  8. print();
  9. }
  10. }

To solve the above problem put the risky code in a try block and handle it in a catch block like below.
  1. class Solution{
  2. public static void print() {
  3. int a=10;
  4. int b=0;
  5. try {
  6. System.out.println(a/b);
  7. }catch(ArithmeticException e) {
  8. System.out.println("Denominator must not be zero");
  9. }
  10. }
  11. public static void main(String[] args) {
  12. print();
  13. }
  14. }
Benefits Of Exception Handling
Abnormal termination of the program is solved.

Exception: It is caused by our program and these are recoverable.
Error: It is not caused by our program, these are due to lack of system resources and these are not recoverable.

Hierarchy of Exception




Checked vs Unchecked Exceptions
The exceptions which are checked by the compiler  are called checked exceptions
Example:
FileNotFoundException
IOException
InterruptedException
The exceptions which are not checked by the compiler are called unchecked exception.
Example:
NullPointerException
ArrayIndexOutOfBoundException

Note 1: RuntimeException and its child classed, Error and its child classes are unchecked and all the remaining are checked exceptions
Note 2: Whether the exception is checked or unchecked compulsory it should occur at runtime only. There is no chance of occurring any exception at compile time.

Keywords related to exception handling: 
try: Put all risky code inside the try block.
catch: Handle exception inside the catch block.
finally: Put resource clean up code inside finally block
throw: To handover our created exception object to the JVM manually.
throws: To delegate the responsibility of exception handling to the caller method.

Default exception handling in java
1. If an exception is raised inside any method then the method is responsible to create an Exception object with the following information.
                                Name of the exception
                                Description of the exception
                                Location of the exception
2. After creating the exception object the method handovers the object to the JVM.
3.JVM checks whether the method contains any exception handling code or not. If the method won't contain any exception handling code then JVM terminates that method abnormally and remove the corresponding entry from the stack.
4.JVM identifies the caller method and checks whether the caller method contains any handling code or not. If the caller method also not contain any exception handling code then JVM terminates that caller also abnormally and removes the corresponding entry from the stack. This process will continue until the main() method. If the main() method also doesn't contain any exception handling code then JVM terminates main() method and removes the corresponding entry from the stack.
5. Then JVM handovers the responsibility to exception handling to the default exception handler.
6.Default exception handler print exception information to the console in the following formats and terminates the program abnormally.
                             Name of the exception: description
                             Location of exception(stack trace)

The possible combination of try, catch and finally

import java.io.FileNotFoundException;
public class PossibleCombination {
public void method() {
try {}catch(NullPointerException e) {}
try {}catch(RuntimeException e) {}
try {}catch(Error e) {}
try {}catch(Exception e) {}
try {}catch(Throwable e) {}
try {}catch(FileNotFoundException e) {}//CE For checked exception it must be raised in the try block then only you can handle it.
try {}catch(RuntimeException e) {}catch(Exception e) {}
try {}catch(NullPointerException e) {}catch(NullPointerException e) {}//CE you can't handle same exception two times.
try{}catch(Exception e) {}finally{}
try{}finally{}catch(Exception e) {}//CE in catch, finally series finally block should be the last block.
try {}catch(RuntimeException e) {}catch(NullPointerException e) {}//CE if there is a relation between the exceptions then first child exception should be handled first then parent.
try {}catch(NullPointerException e) {}catch(RuntimeException e) {}
try {}finally {}
try {}finally {}finally {}//CE atmost one finally block is  allowed. 
}
}

Multi-catch block
In a multi-catch block, you cannot combine catch handlers for two exceptions that share a parent-child relationship. You can only combine catch handlers for exceptions that don't share the parent-child relationship between them.
For example:
try {
throw new FileNotFoundException();
}catch(FileNotFoundException |IOException ex) {
}

Try with Resources
Until 1.6v, it is a programmer nagging to close all open resources(BufferReader, Connection) explicitly.
What's happen, If the programmer will forget to close the resources, It causes a memory leak and therefore effects the performance of the application.
To overcome this problem Java people introduce try-with resource
concept in 1.7v which closes all the open resources automatically. But only those resources which are the child of AutoCloseable or Closeable interface.
All resoure reference variables should be final or effectively final, therfore we can't do reassignment within the try block like below
try(BufferReader br = new BufferReader(new FileReader("test.txt"))){
br = new BufferReader(new FileReader("test.txt"));// invalid, CE
}
Note: We can declare any number of resources but all these resources must be separeted with ";" and finally block is not required . Like below
      try(Resource1;Resource2;Resource3){}

Try-with Resources enhancement
Until 1.8v, the resource reference variables which are created outside of the try block can't be used directly in try-with-resources like below
BufferReader br = new BufferReader(new FileReader("test.txt"))
try(br){
// invalid until 1.8v, Resource reference variables must be local to try block
}

But valid in Java 1.8v onwards
try(BufferReader br1=br){
// valid in 1.8v or higher version
}

But in Java 1.9v onwards
try(br){
// valid in 1.9v or higher version, but make sure resources should be either final or effectively final, means we should not perform reassignment.
}

Custom Exception
You can create a custom exception by extending Exception or RuntimeException as per your business requirement.
If you want to force the caller to handle it, then create your custom exception by extending Exception otherwise create custom exception using RuntimeException.
You can also create by extending Throwable but it is not recommended.

Example
class RecordNotFoundException extends Exception{}
or
class RecordNotFoundException extends RuntimeException{}

Assertions
When creating application programs, you assume many things. However, often it happens that assumptions don't hold, resulting in an erroneous condition.
The assert statement is used to check your assumptions about the program. If assumption test gets fail then JVM will throw AssertionError
For Example:
public class AssertionExample {
public static void main(String[] args) {
int i=Integer.MIN_VALUE;
if(i<0) {
//If negative value, convert into positive value
i=-i;
}
System.out.println("the value of i is :"+i);
assert(i>=0):"impossible i is negative!";
}
}
Note: You have to enable assertion before executing the above program like  below
java -ea AssertionExample
the value of i is :-2147483648
Exception in thread "main" java.lang.AssertionError: impossible i is negative!
        at AssertionExample.main(AssertionExample.java:9)