Suresh Rohan's Blog

This blog is all about Java, J2EE,Spring, Angular, React JS, NoSQL, Microservices, DevOps, BigData, Tutorials, Tips, Best practice, Interview questions, Views, News, Articles, Techniques, Code Samples, Reference Application and much more

Monday, November 2, 2015

Exception Handling in Java

Java has built-in support for exceptions. The Java language supports exception handling in the form of the throw, throws, try, catch, and finally keywords.




Throwing Exceptions


if(args.length == 0) {
// no arguments passed - throw an exception
throw new IllegalArgumentException("No input passed to echo command");
}
the throw keyword followed by the exception object. Here you make use of IllegalArgumentException

Unhandled Exceptions


If there is an exception thrown from a program, and it is left unhandled, the program will terminate abnormally after throwing a stack trace. 

A stack trace shows the list of the method (with the line numbers) that was called before the control reached the statement where the exception was thrown. As a programmer, you’ll find it useful to trace the control flow for debugging the program and fix the problem that led to this exception.

Try and Catch Statements


Java provides the try and catch keywords to handle any exceptions that can get thrown in the code you write.

ScanInt2.java
package com.appfworks.exception;

/**
* Created by suresh on 02/11/15.
*/
// A simple progam to accept an integer from user in normal case,
// otherwise prints an error message
import java.util.*;
class ScanInt2 {
public static void main(String [] args) {
System.out.println("Type an integer in the console: ");
Scanner consoleScanner = new Scanner(System.in);
try {
System.out.println("You typed the integer value: " + consoleScanner.nextInt());
} catch(InputMismatchException ime) {
// nextInt() throws InputMismatchException in case anything otherthan an integer
// is typed in the console; so handle it
System.out.println("Error: You typed some text that is not an integer value...");
}
}
}

The block followed by the try keyword limits the code segment for which you expect that some exceptions could be thrown. If any exception gets thrown from the try block, the Java runtime will search for a matching handler.

an exception handler for InputMismatchException is present, which is of exactly the same type as the exception that got thrown. This exactly matching catch handler is available just outside the try block in the form of a block preceded by the keyword catch, and this catch block gets executed. In the catch block you caught the exception.

Programmatically Accessing the Stack Trace

You can use the printStackTrace() method, which will print the stack trace to the console.

ime.printStackTrace();

You can also access each of the entries in the stack trace. All exceptions have a method named getStackTrace() that returns an array of StackTraceElements.


Multiple Catch Blocks


Note how you provided more than one catch handler by stacking them up: you provided specific (i.e.,derived type) exception handlers followed by more general (i.e., base type) exception handlers. If you provide a derived exception type after a base exception type, you get a compiler error.

ScanInt4.java
package com.appfworks.exception;

/**
* Created by suresh on 02/11/15.
*/
// A program that scans an integer from a given string
import java.util.*;
class ScanInt4 {
public static void main(String [] args) {
String integerStr = "";
System.out.println("The string to scan integer from it is: " + integerStr);
Scanner consoleScanner = new Scanner(integerStr);
try {
System.out.println("The integer value scanned from string is: " +
consoleScanner.nextInt());
} catch(InputMismatchException ime) {
System.out.println("Error: Cannot scan an integer from the given string");
} catch(NoSuchElementException nsee) {
System.out.println("Error: Cannot scan an integer from the given string");
} catch(IllegalStateException ise) {
System.out.println("Error: nextInt() called on a closed Scanner object");
}
}
}

When providing multiple catch handlers, handle specific exceptions before handling general exceptions. If you provide a derived class exception catch handler after  a base class exception handler, your code will not compile.

Multi-Catch Blocks


Java 7 provides a feature named multi-catch blocks in which you can combine multiple catch handlers.

ScanInt5.java
package com.appfworks.exception;

/**
* Created by suresh on 02/11/15.
*/
// A program that illustrates multi-catch blocks
import java.util.*;
class ScanInt5 {
public static void main(String [] args) {
String integerStr = "";
System.out.println("The string to scan integer from it is: " + integerStr);
Scanner consoleScanner = new Scanner(integerStr);
try {
System.out.println("The integer value scanned from string is: " +
consoleScanner.nextInt());
} catch(NoSuchElementException | IllegalStateException multie) {
System.out.println("Error: An error occured while attempting to scan the integer");
}
}
}

Note how you combine the catch handlers together using the | (OR) operator here (the same operator you use for performing bit-wise OR operation on integral values) for combining the catch clauses of NoSuchElementException and IllegalStateException.

In a multi-catch block, you cannot combine catch handlers for two exceptions that share a base- and derived-class relationship. You can only combine catch handlers for exceptions that do not share the parent-child relationship between them.

General Catch Handlers





try {
System.out.println("You typed the integer value: " + consoleScanner.nextInt());
} catch(InputMismatchException ime) {
// if something other than integer is typed, we'll get this exception, so handle it
System.out.println("Error: You typed some text that is not an integer value...");
} catch(Exception e) {
// catch IllegalStateException here which is unlikely to occur...
System.out.println("Error: Encountered an exception and could not read an integer from the
console... ");


}
if the try block throws any other exception than the InputMismatchException, and if that exception is a derived class of the Exception class, this general catch handler will handle it. It is recommended practice to catch specific exceptions, and then provide a general exception handler to ensure that all other exceptions are handled as well.

Chained Exceptions


When you want to catch an exception and throw another exception, you can “chain” the first exception to the thrown exception.

When creating an exception object you can use a constructor that takes another exception as an argument; this passed argument is the exception chained to the exception object being created.

ChainedException.java
package com.appfworks.exception;

/**
* Created by suresh on 02/11/15.
*/
class ChainedException {
public static void foo() {
try {
String [] str = { "foo" };
System.out.println("About to throw ArrayIndexOutOfBoundsException");
// following statement has out-of-bounds access
String functionName = str[10];
} catch(ArrayIndexOutOfBoundsException oob) {
System.out.println("Wrapping ArrayIndexOutOfBoundsException into a RuntimeException");
throw new RuntimeException(oob);
}
}
public static void main(String []args) {
try {
foo();
} catch(Exception re) {
System.out.println("The caught exception in main is: " + re.getClass());
System.out.println("The cause of the exception is: " + re.getCause());
}
}
}


Finally Blocks


The word “resource” refers to any of the classes that acquire some system sources from the underlying operating system, such as network, file, database, and other handles.

how do you know which classes need to be closed? Well, nice question. The answer is that if a class implementsjava.io.Closeable, then you must call the close() method of that class; otherwise, it will result in a resource leak.

The garbage collector (GC) is responsible for releasing only memory resources. If you are using any class that acquires system resources, it is your responsibility to release them by calling the close()  method on that object.

finally block is provided after the catch block. This finally block will be executed whether an exception has occurred or not.

if you call System.exit()  inside a method, it will abnormally terminate the program. so, if the calling method has a finally block, it will not be called and resources may leak. For this reason, it is a bad programming practice to call System.exit()  to terminate a program.

ScanInt7.java
package com.appfworks.exception;

/**
* Created by suresh on 02/11/15.
*/
import java.util.*;
class ScanInt7 {
public static void main(String [] args) {
System.out.println("Type an integer in the console: ");
Scanner consoleScanner = new Scanner(System.in);
try {
System.out.println("You typed the integer value: " +
consoleScanner.nextInt());
} catch(Exception e) {
// call all other exceptions here ...
System.out.println("Error: Encountered an exception and could not read an integer from the console... ");
System.out.println("Exiting the program - restart and try the program again!");
} finally {
System.out.println("Done reading the integer... closing the Scanner");
consoleScanner.close();
}
}
}


No comments:

Post a Comment