Approach Java(4)

Free Online Courses With Personalized Certificate
September 2, 2010
Exception Handling
Topics in this chapter:
-
Overview
-
Exception Types
-
Java Class Hierarchy for Exceptions
-
Checked Exceptions with Code examples
-
Unchecked Exceptions with Code examples
-
When to use checked/unchecked exceptions
-
Common Exception class methods
-
Creating your own exceptions
Overview
When we write programs we know there can be exceptional cases, we can also call them unwanted cases but they are there and we need to do something about them. For example, while reading a file there’s a possibility that somebody changed file permissions and it is no more readable. You may say we can check manually before reading, yes we can but a program may have to read a file who’s path was passed to it at runtime.
Similarly for a program accessing a database, if somehow SQL query finds a table or column missing this will be an exceptional case.
Java supports exception handling for such scenarios.
In this chapter we will read about how to use exception handling in Java and best practices for the same.
Exception Types
There are 3 categories in which exceptional cases are divided in Java:
-
Checked Exceptions
-
Unchecked Exceptions
-
Errors
Checked exceptions are those which client/caller program will have to handle. Programmer, while writing a program, will have to consider checked exceptions and handle them explicitly. Compiler will not let the program compile unless all checked exceptions are explicitly handled. Another view to look at checked exceptions is that programmer is made aware of potential exceptional cases with program so that he/she can take appropriate action to handle those cases. Handler code may be to recover from that scenario and follow an alternate course of action.
Unchecked exceptions are runtime exceptions which are programming mistakes, they can be avoided by writing better code. One example of unchecked exception is “divide by zero”. But it may not be always possible to detect runtime exceptions beforehand hence these generally are not handled explicitly. Compiler will not force us to handle unchecked exceptions.
Errors in Java are abnormal conditions from which programs cannot recover. Like disk failure and JVM crash.
Note that on the implementation level Error, Unchecked and checked exceptions are all Java classes.
Java Class Hierarchy for Exceptions
We will go through code examples but before that let’s look at Java class hierarchy for exceptions and errors.
Throwable – Super class of all exceptions and errors in Java
Throwable has 2 subclasses - Error and Exception
Error – Error is a subclass of Throwable that indicates abnormal scenario. Programs do not need to handle them
Exception - Exception is a subclass of Throwable that represents both Checked and Unchecked exceptions. All checked exception classes in Java extend Exception class. All unchecked exceptions in Java extend RuntimeException class, which is a subclass of Exception class. RuntimeException class is special because programs do not need to handle it or any of its subclasses.
Checked Exceptions with Code examples
Let’s now look at some examples and how to handle exceptions in programs:.
Checked Exception Example
Save the code below under package “exceptions” and filename Cexception.java
package exceptions;
import java.io.BufferedReader;
import java.io.FileReader;
public class CException {
private String filePath;
public CException(String filePath) {
super();
this.filePath = filePath;
}
public void printFileContents()
{
BufferedReader bReader = new BufferedReader(new FileReader(this.getFilePath()));
}
public static void main(String[] args)
{
CException ceObject = new CException(“/home/varun/Desktop/unknownfile.txt”);
ceObject.printFileContents();
}
public String getFilePath() {
return filePath;
}
}
Compile it:
>javac exceptions/CException.java
exceptions/CException.java:15: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
BufferedReader bReader = new BufferedReader(new FileReader(this.getFilePath()));
^
1 error
Program fails to compile and above errors tells the programmer to handle checked exception java.io.FileNotFoundException. Because non-existence of file is a likely cause of failure so programmer needs to handle it and write code for action he wants to take in this scenario.
Error also says exception must be caught or declared to be thrown. This proves 2 points:
-
Checked exceptions need to be paid attention to, programmer cannot ignore them
-
They must be handled either by catching them or by declaring them to be thrown
Caching exceptions
In Java, exceptions can be caught with try/catch block. That means any piece of code that throws a checked exception is put under try block and catch block catches the exception. See the changed code below:
package exceptions;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class CException {
private String filePath;
public CException(String filePath) {
super();
this.filePath = filePath;
}
public void printFileContents()
{
try {
BufferedReader bReader = new BufferedReader(new FileReader(this.getFilePath()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args)
{
CException ceObject = new CException(“/home/varun/Desktop/unknownfile.txt”);
ceObject.printFileContents();
}
public String getFilePath() {
return filePath;
}
}
Note this code segment:
try {
BufferedReader bReader = new BufferedReader(new FileReader(this.getFilePath()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Now new BufferedReader(new FileReader(this.getFilePath())) statement is put under try {} block and catch block is catching FileNotFoundException. In caseFileNotFoundException occurs, code within cache block will be executed. Depending on the requirement programmer can write code in cache block to handle that scenario. For now we are just printing the exception stacktrace that will tell us
Now compilation will succeed.
Throwing Exceptions
Sometimes programmer does not know how to handle exception or he thinks current method is not the right place to catch exception. In this scenario ‘catch block’ is not the requirement here. Instead Java supports ‘throws’ keyword to throw the exception to caller (api client). This is how throws syntax looks like:
package exceptions;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class CException {
private String filePath;
public CException(String filePath) {
super();
this.filePath = filePath;
}
public void printFileContents() throws FileNotFoundException
{
BufferedReader bReader = new BufferedReader(new FileReader(this.getFilePath()));
}
public static void main(String[] args)
{
CException ceObject = new CException(“/home/varun/Desktop/unknownfile.txt”);
ceObject.printFileContents();
}
public String getFilePath() {
return filePath;
}
}
In above code, throws FileNotFoundException syntax with method signature says ‘I am not catching the exception, I am throwing it to my caller program/method (in this case main() method), you handle it’. No try/catch block is used.
Compile this program now:
>javac exceptions/CException.java
exceptions/CException.java:22: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
ceObject.printFileContents();
^
1 error
Note that now error is on the client side (main() method) because now it is client’s responsibility to handle thrown exception. Again main() method has same 2 ways to handle it – either catch it using try/catch block or throw it further. Beyond main, this exception goes to JVM which will print the stacktrace in console. Let’s try that in code below by throwing this exception further:
package exceptions;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class CException {
private String filePath;
public CException(String filePath) {
super();
this.filePath = filePath;
}
public void printFileContents() throws FileNotFoundException
{
BufferedReader bReader = new BufferedReader(new FileReader(this.getFilePath()));
}
public static void main(String[] args) throws FileNotFoundException
{
CException ceObject = new CException(“/home/varun/Desktop/unknownfile.txt”);
ceObject.printFileContents();
}
public String getFilePath() {
return filePath;
}
}
Now main() method also throws the exception hence it does not need try/catch block.
Compilation will work now.
Let’s run the program with a non existing file:
> java exceptions.CException
Exception in thread “main” java.io.FileNotFoundException: /home/varun/Desktop/unknownfile.txt (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.io.FileInputStream.<init>(FileInputStream.java:66)
at java.io.FileReader.<init>(FileReader.java:41)
at exceptions.CException.printFileContents(CException.java:16)
at exceptions.CException.main(CException.java:22)
Above is the stacktrace of exception. JVM prints the sequence of CEException method calls and into JDK methods (read bottom to top) and finally exits the program after printing stacktrace.
We will continue with other topics in next lesson….
Friday, November 19, 2010 8:54 AM
From:”Varun Chopra” <varunspace@yahoo.com>Add sender to ContactTo:
hpufriends@googlegroups.com, “Hpumca” <hpumca@yahoogroups.com>
- Unchecked Exceptions with Code examples
- Common Exception class methods
- Creating your own exceptions
- When to use checked/unchecked exceptions
Exception Handling – Lesson 3 – April 15, 2011
We have following topics remaining in Exception Handling Chapter:
- Common Exception class methods
- Creating your own exceptions
- When to use checked/unchecked exceptions
Let’s cover Common Exception class methods in this lesson.
Common Exception class methods
java.lang.Exception class extends java.lang.Throwable class which provides these common methods:
printStackTrace() – To print exception stack trace (log of chain of exceptions) on console
printStackTrace(PrintWriter p) – To print exception stack trace (log of chain of exceptions) in a print writer object (like a file)
getMessage() – Returns message attached with the exception (String object)
getCause() – Returns the actual exception object which was cause of problem (the root reason)
Go through this code example and comments in green to understand more about above methods:
package pkg1;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.sql.SQLWarning;
public class ExceptionMethods {
public static void main(String[] args) throws FileNotFoundException
{
ExceptionMethods ext = new ExceptionMethods();
try {
ext.forceException();//call a method that will throw an exception
} catch (Exception exception) {
System.err.println(“exception.printStackTrace() OUTPUT:”);
System.err.println(“———————————–”);
exception.printStackTrace();
System.err.println(“exception.printStackTrace(PrintWriter p) OUTPUT goes to the file“);
System.err.println(“———————————–”);
PrintWriter printWriter = new PrintWriter(new File(“/home/varun/Desktop/exception.log”));
exception.printStackTrace(printWriter);
printWriter.flush();
printWriter.close();
System.err.println(“\nexception.getCause() OUTPUT:”);
System.err.println(“———————————–”);
Throwable causeEx = exception.getCause();//note that getCause itself is an exception
System.err.println(causeEx.getClass());
System.err.println(“\nexception.getMessage() OUTPUT:”);
System.err.println(“———————————–”);
System.err.println(exception.getMessage());
}
}
private void forceException() throws Exception
{
try
{
//call anotherMethod to receive exception
forceException0();
}
catch(SQLException ex)
{
throw new Exception(ex);
}
}
private void forceException0() throws SQLWarning
{
throw new SQLWarning(“Invalid Database Table Name”);
}
}
Output on running above program:
exception.printStackTrace() OUTPUT:
———————————–
java.lang.Exception: java.sql.SQLWarning: Invalid Database Table Name
at pkg1.ExceptionMethods.forceException(ExceptionMethods.java:53)
at pkg1.ExceptionMethods.main(ExceptionMethods.java:21)
Caused by: java.sql.SQLWarning: Invalid Database Table Name
at pkg1.ExceptionMethods.forceException0(ExceptionMethods.java:59)
at pkg1.ExceptionMethods.forceException(ExceptionMethods.java:49)
… 1 more
exception.printStackTrace(PrintWriter p) OUTPUT goes to the file
———————————–
exception.getCause() OUTPUT:
———————————–
class java.sql.SQLWarning
exception.getMessage() OUTPUT:
———————————–
java.sql.SQLWarning: Invalid Database Table Name
Exception Handling – Lesson 4
- April 18, 2011
We have following topics remaining in Exception Handling Chapter:
- Creating your own exceptions
- When to use checked/unchecked exceptions
Let’s cover Creating your own exceptions in this lesson.
Creating your own exceptions
By extending java.lang.Exception class you can write your own exception classes. You may be thinking why would I do that when there are so many different exception classes provided by Java. Well, you may not need it most of the times but sometimes you do. First of all you may need to pass data (some objects) with the exception to the caller to help it get more details about runtime state (with Java exceptions you can pass a string only). Secondly you may like to throw exception with appropriate name that makes sense and you may not find any matching your requirement in Java.
Here is an example that creates a custom exception class MyOwnException which also holds a Data class object. Exception is thrown if number of arguments passed to checkData() method is less than 2.
package pkg1;
public class MyExceptionClass {
public static void main(String[] args)
{
MyExceptionClass ext = new MyExceptionClass();
try {
System.out.println(“Result when no data passed”);
ext.checkData();
} catch (InSufficientDataException e) {
e.printStackTrace();
System.out.println(e.getData());
}
try {
System.out.println(“\nResult when single argument is passed”);
ext.checkData(10);
} catch (InSufficientDataException e) {
e.printStackTrace();
System.out.println(e.getData());
}
}
private void checkData(int… values) throws InSufficientDataException
{
int length = values==null?0:values.length;
if (length < 2)
{
Data data = new Data(null, null);
if (length == 1)
{
data = new Data(values[0], null);
}
throw new InSufficientDataException(“Data Length is “+length, data);
}
}
}
class InSufficientDataException extends RuntimeException
{
private Data data;
InSufficientDataException(String message, Data data)
{
super(message);
this.data = data;
}
public Data getData() {
return data;
}
}
class Data
{
Integer a;
Integer b;
Data(Integer a, Integer b)
{
this.a = a;
this.b = b;
}
@Override
public String toString() {
return “Data [a=" + a + ", b=" + b + "]“;
}
}
Output on running above program:
Result when no data passed
pkg1.InSufficientDataException: Data Length is 0
at pkg1.MyExceptionClass.checkData(MyExceptionClass.java:37)
at pkg1.MyExceptionClass.main(MyExceptionClass.java:11)
Data [a=null, b=null]
Result when single argument is passed
pkg1.InSufficientDataException: Data Length is 1
at pkg1.MyExceptionClass.checkData(MyExceptionClass.java:37)
at pkg1.MyExceptionClass.main(MyExceptionClass.java:19)
Data [a=10, b=null]
Exception Handling – Lesson 5, April 25, 2011
We have this last topic remaining in Exception Handling Chapter:
- When to use checked/unchecked exceptions
Let’s cover it in this lesson.
When to use checked/unchecked exceptions
When you have to throw an exception from a method should you throw a checked exception or unchecked? Answer is – it depends. Basically if the caller can take care of the exceptional case at program writing time then you should throw a checked exception. That means you want to give an explicit message to calling program that if you call my method this is the exceptional case – have you taken this into account? If you know that calling program cannot do anything if the exception occurs there is no point in forcing the caller to catch exception. In such a case unchecked exception is the solution.
For e.g. JDBC forces user to catch SQLException while connecting to database. SQLException is a checked exception. Assumption probably was user will write some alternate code to connect in catch block. But later on when Spring framework was launched and they provided their own apis to connect to database (wrapper over JDBC), they converted all JDBC checked exceptions to unchecked. Their point was user will not be in a position to work around this fatal problem. So there is no use of forcing the user to catch exceptions he cannot do anything about.
Let me know if you have any question on this topic and we will carry forward this discussion.
With this we have wrapped up chapter 7. Next chapter is “File Handling”.
Here’s the status:
Already covered:
1. Introduction to OOPs
2. Java Overview (P/F independence, versions, JRE, JDK)
3. Java programming basics (class structure, compiling & executing programs, member variables, methods, constructors, creating objects, data types)
4. Introduction to Packages and scope identifiers (import statement as well)
5. Adding power to language (Conditional constructs, loops and more)
6. Data Structures (Collections)
7. Exception Handling
Next Chapter
8. File Handling
Still to come
9. JDBC
10. Closing and Forward

