Java Exception Handling - ashwin-shetty/Documents-Wiki GitHub Wiki

Content

Exceptions _

Exceptions can be caused by bad code or due to environment or configuration issue.

Two keys of exception handling

  1. Friendly message to end user
  2. Enough information to Debug the problem
 public void basicExceptionMethod() {
        try {
            String str = null;
            str.length();
            System.out.println("End Method");
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    } 
 1. In exception there is a Hierarchy ex: NullPointerException extends RuntimeException , RuntimeException extends Exception, Exception is the superclass
 2. Can have multiple catch block 
 3. Can have multiple strategy for catch block
 4. if the exception is not handled in the method then it has to handled in the calling method, otherwise subsequent method would not be executed.
 5. if any other exception occurs which is not handled then exception would occur. 
 6. catch block hierarchy should always be from subclass to super class Exception.
 7. in java 7- you can add multiple exception in the same block
	
       ex: catch(IOException | SQLException ex)
		{
		ex.printStackTrace();
		}
	

Consider below example,

// Example 1
// Try block throws null pointer exception
// use more specific NullPointerException instead of  Exception(since NullPointerException is the subclass of Exception)
	private static void method1() {
        try {
            String str = null;
            str.length();
            
        }
        catch (NullPointerException ex)
        {
            System.out.println("null pointer expception");
        }
        
       
    }
// Example 2
// Here  we are calling the 4th element of array "i" which does not exist so it throws "ArrayIndexOutOfBoundsException" 
// use ArrayIndexOutOfBoundsException exception instead of Exception class
	private static void method1() {
        try {
           
            int[] i = {1,2,3};
            int num = i[3];
        }
        
        catch(ArrayIndexOutOfBoundsException ex){
            System.out.println("ArrayIndexoutofBoundException");
        }
       
    }

Finally Block

_ Whenever there a object creation and exception occurs then there is a leakage of objects because you are not closing the object. That why you need to use Finally block which exchicutes even if there is exception occurs or not.

	public class FinallyRunner {
    public static void main(String[] args) {
        Scanner scanner =  null;
        try {
            scanner = new Scanner((System.in));
            int[] n = {1, 2, 3, 4};
            int number = n[0];
        }
        catch(ArrayIndexOutOfBoundsException ex){
            ex.printStackTrace();
        }
        finally {
            System.out.println("in final block");
            scanner.close();
        }
        System.out.println("after final block");
    }
}
	* Finally block will not be executed, when code in the finally block throws an exception or jvm crashes
	* you can have try block followed by finally block without catch block.(here 'try' block executes code and finally helps in closing it)
	* Try block without catch and finally will not compiled	

Checked Exceptions vs Unchecked Exceptions

Exceptions hierarchy
1. Error extends Throwable()
2. Exceptions extends Throwable()
3. InterruptedExceptions extends Exceptions()
4. RuntimeExceptions extends Exceptions()
5. NullPointerExceptions extends Exceptions()
		
1. Error cant be handled
2. In Exceptions there are 2 types checked (which is risky) and unchecked Exceptions
3. checked exceptions are compile time exceptions - then the calling method can  either by "try- catch" block or throw it
4. RuntimeExceptions usually happens due to bad programming which is need not be handled , can be thrown - so the calling method need not handle it-need not do anything about it.

Throwing the checked Exception

checked excpetion can be either thrown or handled by calling method

package com.ashu.exceptions;

class Amounts{


    private String currencys;
    private int Amounts;
    public Amounts(String currency, int amount) {
        this.currencys = currency;
        Amounts = amount;
    }
    public void add(com.ashu.exceptions.Amounts that) throws Exception {
        if(!this.currencys.equals(that.currencys)) {
            throw new Exception("Currency don't match" + this.currencys  + "&" + that.currencys);
        }
        this.Amounts = this.Amounts + that.Amounts;
        System.out.println(this.currencys + this.Amounts);
    }
    @Override
    public String toString() {
        return "Amount{" +
                "currency='" + currencys + '\'' +
                ", Amount=" + Amounts +
                '}';
    }



}
public class CheckedExceptions {
    public static void main(String[] args) throws Exception {
        Amounts a1 = new Amounts("USD",10);
        Amounts a2 = new Amounts("EUR", 20);
        a1.add(a2);
        System.out.println(a1);

    }
}

Throwing an Exception - Runtime Exception

class Amount{


    private String currency;
    private int Amount;
    public Amount(String currency, int amount) {
        this.currency = currency;
        Amount = amount;
    }
    public void add(Amount that){
        if(!this.currency.equals(that.currency)) {
            throw new RuntimeException("currency symbol is not equal" + this.currency  + "&" + that.currency);
        }
        this.Amount = this.Amount + that.Amount;
        System.out.println(this.currency + this.Amount);
    }
    @Override
    public String toString() {
        return "Amount{" +
                "currency='" + currency + '\'' +
                ", Amount=" + Amount +
                '}';
    }



}
public class RunTimeExceptions {
    public static void main(String[] args) {
Amount a1 = new Amount("USD",10);
Amount a2 = new Amount("EUR", 20);
a1.add(a2);

    }
}

Throwing the custom exception

_

package com.ashu.exceptions;

class Amounts{
    private String currencys;
    private int Amounts;
    public Amounts(String currency, int amount) {
        this.currencys = currency;
        Amounts = amount;
    }
    public void add(com.ashu.exceptions.Amounts that) throws CurrenciesDoNotMatchException {
        if(!this.currencys.equals(that.currencys)) {
            throw new CurrenciesDoNotMatchException("Currency don't match" + this.currencys  + "&" + that.currencys);
        }
        this.Amounts = this.Amounts + that.Amounts;
        System.out.println(this.currencys + this.Amounts);
    }
    @Override
    public String toString() {
        return "Amount{" +
                "currency='" + currencys + '\'' +
                ", Amount=" + Amounts +
                '}';
    }

class CurrenciesDoNotMatchException extends Exception{
    public CurrenciesDoNotMatchException(String message) {
       super(message);
    }
}

}

public class CheckedExceptions {
    public static void main(String[] args) throws Amounts.CurrenciesDoNotMatchException {
        Amounts a1 = new Amounts("USD",10);
        Amounts a2 = new Amounts("EUR", 20);
        a1.add(a2);
        System.out.println(a1);

    }
}

Try with resources

From java 7 if a resource implements AutoCloseable interface(Directly or by its Parent class) then we can write try block without catch and finally. Inside try block paranthesis objects will autoclose it.

package com.ashu.exceptions;

import java.util.Scanner;

public class FinallyRunner {
    public static void main(String[] args) throws ArrayIndexOutOfBoundsException {
        try (Scanner scanner = new Scanner((System.in))) {
            int[] n = {1, 2, 3, 4};
            int number = n[5];

            //try block executed scanner wont be null
        }

    }
}

Exception handling best practice

_

  1. Never hide exceptions.
  2. Do not use it for flow control
  3. Think about the user.
  4. Think about the support team.
  5. Think about the calling method.
  6. Have global exception handling.