Java exceptions code and rules

try – catch – finally


try {

//This is where you try your code

}
catch (Exception e) {

//If an exception occurs, it is caught here
//You can have multiple catch blocks for each different Exception, e.g. ArrayOutOfBoundsException, FileNotFoundException, etc.

}
finally {

//This is where you tidy up, close files that sort of thing
//This code ALWAYS executes, regardless if an exception is thrown
//There is only ever one instance of the finally in a try-catch-finally block

}

There are Java Exception, stack overflow, array index out of bounds, etc, but you can also create your own. Exceptions are thrown, hence they are caught when you try the code. You can stack try-catch-finally, e.g. try some code, and then try code within that code.

public class ExceptionExample {
	public static void main(String[] args) {
		int counter = 0;
		int[] arr = new int[] {1,2,3,4};
		
		try {
			System.out.println(arr[4]);
			counter = 1;
		}
		catch (ArrayIndexOutOfBoundsException ae) {
			System.out.println("An exception has been caught!");
		}
		finally {
			counter = counter + 10;
		}
		
		System.out.println(counter); //this prints 10 because the exception was thrown, otherwise it would print 11
	}
}

If there is a return statement in the catch, the finally is still executed!

The finally does not execute only when:

Application termination (try or catch execute Sysem.exit())
Fatal errors – the JVM crashes


public class ExceptionExample {

	int getInt() {
		int res = 0;
		int[] arr = new int[] {1,2,3,4};
		
		try {
			System.out.println(arr[4]);
			
		}
		catch (ArrayIndexOutOfBoundsException ae) {
			res = 1;
			System.out.println("An exception has been caught!");
			return res;    //Because this is here, even though finally is executed the value returned will be 1 as this is the designated return value.
		}
		finally {
			res = res + 100;
		}
		return res;
	}
	public static void main(String[] args) {
		
		ExceptionExample t = new ExceptionExample();
		System.out.println(t.getInt());
	}
}

The above applies to a primitive. For an object, the finally does affect the value returned because you are referencing the object. It can’t modify the primitive return type.


	StringBuilder getValue() {
		StringBuilder res = new StringBuilder("10");
		int[] arr = new int[] {1,2,3,4};
		
		try {
			System.out.println(arr[4]);
		}
		catch (ArrayIndexOutOfBoundsException ae) {
			System.out.println("An exception has been caught!");
			return res;    
		}
		finally {
			res.append(100);
		}
		return res;
	}
	public static void main(String[] args) {
		
		ExceptionExample t = new ExceptionExample();
		System.out.println(t.getInt());    //This returns 10100
	}

Some rules:

A try block can be followed by a catch or finally block, or both. However, if the code in the try can throw a checked exception then this needs to be thrown by your method.
A finally block cannot appear before a catch

The order of the exceptions do matter when the classes are related. If you try to catch an exception of the base before the derived then the code will not compile. As an example, FileNotFound would come before IOException, as this reflects both the hierarchy and logic 🙂

You can catch and/or throw exceptions, so your code can try, then catch an exception and re-throw it. However if your code does re-throw it you must declare this.

import java.io.*;

public class ExceptionExample {
	FileInputStream fis;
	
	public void load() throws FileNotFoundException {  //You need to declare this otherwise it fails to compile
		try {
			fis = new FileInputStream("file.txt");
		}
		catch (FileNotFoundException fnf) {
			throw fnf;
		}
	}
}

Alternatively you can just throw, without having to check anything:

public void load() throws IOException {
	fis = new FileInputStream("file.txt");
	fis.close();
}
Categories

There are three categories:

  • Checked
  • Runtime
  • Errors
  • FileNotFound is a checked exception, it is thrown if the file cannot be found. A checked exception is a subclass of the java.lang.Exception class, but not a subclass of java.lang.RuntimeException.

    If a method uses a method which may throw a checked exception, it must

  • use try-catch block
  • and/or

  • throw the exception in the methods signature
  • Not doing this means the code will fail to compile.

    By declaring these exceptions, the user is aware of the exception that could occur and writes code to handle this.

    Runtime exceptions, also known as unchecked exceptions, an example is NullPointerExeption. These represent a programming error (e.g. you didn’t instantiate an object). It is a subclass of java.lang.RuntimeException.

    You can catch runtime exceptions. Saying that you can prevent runtime exceptions by using code as well.

    
    //This code will through a runtime exception
    
    int[] arr = new int[] {0,2,4,6,8};
    
    System.out.println(arr[5]);  //This is the runtimeexception!
    
    //This code uses a try-catch block
    
    try {
    	System.out.println(arr[5]);
    }
    catch (ArrayIndexOutOfBoundsException e) {
    	System.out.println("the array is not as big as you think...");
    }
    
    //However, you could just use logic....
    
    if (arr.length > 5) {
    	System.out.println(arr[5]);
    }
    

    Finally there are Errors. An example of which is StackOverflowError, this is thrown by the JVM when the size of the memory required is too large. It is a serious exception.
    Errors are a subclass of java.lang.Error.
    Errors are not part of a method signature.
    Errors can be caught by an exception handler, but should not be.

    Common exceptions
    ArrayIndexOutOfBoundException

    As previously covered, you are trying to reference an array entry outside of the limits (positive or negative).

    
    int[] arr = new int[] {0,2,3,5,6};
    
    System.out.println(arr[5]);
    System.out.println(arr[-1]);
    
    
    IndexOutOfBoundsException

    You are trying to reference an ArrayList entry outside of the limits (positive or negative).

    
    ArrayList<String> as = new ArrayList<String>();
    
    as.add("hello");
    as.add("world");
    
    System.out.println(as.get(100));
    System.out.println(as.get(-1));  //Both throw IndexOutOfBoundsException
    
    

    Simply, check the size of your Array / ArrayList before referencing entry.

    ClassCastException

    This is caused when you try and cast an object into something it is not part of:

    ArrayList<Employee> ees = new ArrayList<Employee>();
    ees.add(new Programmer());
    ees.add(new Manager());
    		
    Employee e1 = (Manager)ees.get(0);
    

    This can be easily resolved by validating the instanceof the object before casting:

    ArrayList<Employee> ees = new ArrayList<Employee>();
    ees.add(new Programmer());
    ees.add(new Manager());
    	
    if (ees.get(0) instanceof Manager) {
    	Employee e1 = (Manager)ees.get(0);
    }
    
    IllegalArgumentException

    This is thrown when the wrong value is passed into an argument. Think password, it must be 6 characters long:

    
    ...
    
    public void checkPassword(String password) throws IllegalArgumentException {
    	
    	if (password == null || password.length() < 6) {
    		throw new IllegalArgumentException("Password incorrect, please enter a password which is atleast 6 characters long");
    	}
    }
    
    ...
    
    public static void main(String[] args) {
    	try {
    		t.checkPassword(null);
    	}
    	catch (IllegalArgumentException ia)
    	{
    		System.out.println(ia.getMessage());   //This will print the message from the method
    	}
    }
    
    IllegalStateException

    From the Java API documentation, this “signals that a method has been invoked at an illegal or inappropriate time”.

    An example, a transfer:

    class Account {
    	private int accountNumber;
    	private double totalAmount;
    	private double transferAmount;
    	private boolean transfer;
    	
    	public void createTransfer(double amt) {
    		if (amt < totalAmount) {
                            totalAmount = totalAmount - amt;
    			transferAmount = amt;
    		}
    	}
    	
    	public void transfer() {
    		//code to send the money
    		transfer = true;
    	}
    	
    	public void modifyTransfer(float amt) {
    		if (!transfer) {
    			createTransfer(amt);
    		}
    		else {
    			throw new IllegalStateException("Money already being transferred");
    		}
    	}
    }
    
    public class ExceptionExample {
    	public static void main(String[] args) {
    		Account a = new Account();
    		try {
             		a.createTransfer(100.00);
    	        	a.transfer();
    		        a.modifyTransfer(150.00);
    		}
    		catch (IllegalStateException is) {
    			System.out.println(is.getMessage());
    		}
    	}
    }
    
    NullPointerException

    It occurs when:

  • reference variable that is explicitly assigned a null value
  • reference variable which has not been initialised
  • An unitialised local variable
  • Accessing nonexistent array positions
  • Using members of an array where the element is null
  • Some examples:

    class ExampleException {
    	static ArrayList<String> list = null;
    	public static void main(String[] args) {
    		list.add("Hello"); // this will throw a null pointer exception
    
    		//You can prevent null pointer by checking the object
    
    		if (list != null) {
    			list.add("hello");
    		}
    
    		//However, if list was defined here:
    		ArrayList<String> list2;
    		if (list2 != null) {           //This would fail to compile - as local variables are not assigned a value
    			list2.add("hello");
    		}
    

    Another:

    class ExampleException {
    	static String[] strArr;
    	public static void main(String[] args) {
    		System.out.println(artArr[1]);  //This will throw a NullPointerException
    		//strArr is assigned null as it is a static. It's elements are not initialised
    		
    		String[] secondArr = new String[4];
    		
    		System.out.println(secondArr[1].toString()); //This will throw a NullPointerException
    		//This is because you are calling the method toString() on the null string
    		System.out.println(secondArr[1]); //this is fine, it will print null
    	}
    }
    

    NumberFormatException

    This is thrown when an invalid string, for example, is converted to a “number”:

    
    System.out.println(Interger.parseInt("ABCD"));  //This will throw a NumberFormatException
    System.out.println(Interger.parseInt("24_68"));  //This will throw a NumberFormatException, the underscore in the string
    System.out.println(Interger.parseInt("+246")) //All fine.
    
    //If we take the first example, this can be parsed by passing in a parameter:
    
    System.out.println(Interger.parseInt("ABCD", 16));
    
    
    ExceptionInInitializerError

    Thrown when a static initializer in the code throws a runtimeexception:

    //An example
    static {
    	int number = Integer.parseInt("65v", 16);
    }
    

    This error can only be caused by runtimeexceptions.

    StackOverflowError

    This should be managed by the JVM, it is thrown when the program calls itself too many times.

    NoClassDefFoundError

    A really annoying error when your classpath is not set, or not inclusive. You do not handle this with code, you just suffer trying to set the classpath 🙂

    OutOfMemoryError

    Thrown when you have exhausted the memory on the heap.

    reference: http://www.manning.com/gupta/

    Advertisements

    Tags: , ,

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s


    %d bloggers like this: