Labels

.NET Job Questions About Java Absract class Abstract class Abstract Class and Interface Aggregation ajax aop apache ofbiz Apache ofbiz tutrial Association authentication autocad basics batch Binary Tree bootstrap loader in java build Builder design pattern C++ Job Questions caching CallableStatement in java certifications Chain of responsibility Design pattern charts check parentheses in a string Classes classloader in java classloading concept code quality collage level java program Composition concurrency Concurrency Tutorial Converting InputStream to String Core Java core java concept core java interview questions Core Java Interview Questions Core Java Questions core java tutorial CyclicBarrier in Java data structures database Database Job Questions datetime in c# DB Db2 SQL Replication deserialization in java Design Patterns designpatterns Downloads dtd Eclipse ejb example/sample code exception handling in core java file handling injava File I/O vs Memory-Mapped Filter first program in spring flex Garbage Collection Generics concept in java grails groovy and grails Guice Heap hibernate Hibernate Interview Questions how-to IBM DB2 IBM DB2 Tutorial ide immutable Interceptor Interface interview Interview Questions for Advanced JAVA investment bank j2ee java JAVA Code Examples Java 7 java changes java class loading JAVA Classes and Objects Java Classloader concept Java classloading concept java cloning concept java collection Java collection interview questions Java Collections java concurrency Java CountDownLatch java definiton Java design pattern Java EE 5 Java EE 6 Java Exceptions Java file Java Garbage Collection Java generics Java Glossary java hot concept java immutable concept Java Interface Java interview Question java interview question 2012 java interview question answer Java Interview Questions Java Interview Questions and Answers java interview topic java investment bank Java Job Questions java multithreading java multithreading concept java new features Java Packages java proxy object java questions Java Serialization Java serialization concept java serialization interview question java session concept java string Java Swings Questions java synchronization java threading Java Threads Questions java tutorial java util; java collections; java questions java volatile java volatile interview question Java Wrapper Classes java.java1.5 java.lang.ClassCastException JavaNotes javascript JAX-WS jdbc JDBC JDBC Database connection jdk 1.5 features JDK 1.5 new features Concurrent HashMap JMS interview question JMS tutorial job JSESSIONID concept JSESSIONID interview Question JSF jsp JSP Interview Question JSP taglib JSTL with JSP Junit Junit Concept Junit interview question.Best Practices to write JUnit test cases in Java JVM Linux - Unix tutorial Marker Interfaces MD5 encryption and decryption messaging MNC software java interview question musix NCR java interview question Networking Job Questions news Object Serialization Objects ojdbc14.jar OOP Oracle Oracle SQL Query for two timestamp difference orm own JavaScript function call in Apache ofbiz Packages Palm Apps patterns pdf persistence Portal Portlet Spring Integration Prime number test in java programs Rails Reboot remote computers REST Ruby Sample application schema SCJP security Senior java developer interviews servlet3 servlets session tracking singleton design pattern Spring Spring 2.5 Framework spring ebook Spring framework concept spring MVC spring pdf Spring Security Spring Security interview questions SQL SQL performance SQL Query to create xml file Sql Query tuning ssis and ssrs StAX and XML string concept string immutable string in java strings struts Struts2 Struts2 integration synchronization works in java Technical Interview testing tips Tomcat top Tutorial Volatile in deep Volatile working concept web Web Developer Job Questions web services weblogic Weblogic Application Server websphere what is JSESSIONID xml XML parsing in java XML with Java xslt


Friday, 5 July 2013

Sun Tech Tip

BEST PRACTICES IN EXCEPTION HANDLING

Exception handling is a built-in aspect of the Java programming language. The concept of handling error cases with exceptions is designed to make code more reliable and easier to maintain and read. This tip looks at some best practices for dealing with and handling exceptions.

As a quick refresher, here's the full construct for exception handling:

   try {

// code which could potentially
// throw an exception

} catch (TheException1 e) {

// code to handle exceptional condition

} catch (TheException2 e) {

// code to handle next exceptional condition

} finally {

// code to run whether an exceptional
// condition happened or not

}

Basically, code that might throw an exception goes within a try block. A specific catch block code runs only if the exception identified for it occurs (or its subclass). However, the code in the finally block runs under all conditions -- this even includes the case when the try-catch code calls return to exit out of the current method.

The try block is required. Additionally, one of the two blocks, catch or finally, must be present, or the compiler will complain.

Given that you can have multiple catch clauses, the system finds the first one that matches the exceptional condition. So, if you have a catch block for an IOException, and a FileNotFoundException happens, this is caught by the general IOException catch clause.

This suggests a best practice for exception handling: Always work with as specific an exception as possible. For instance, if you create a method that could generate a FileNotFoundException, don't declare that method to throw an IOException. If you do, it forces the caller to handle all IOExceptions that are possible, not just FileNotFoundExceptions. You shouldn't get too specific though. In particular, the declared exception thrown by a method should never reveal implementation details.

Another best practice is try to avoid empty catch blocks. In other words, don't ignore exceptions when they happen.

   // This code is bad

try {
...
} catch (AnException e) {
}

The designers of system libraries throw exceptions for a reason: to tell you some exceptional condition happened. It's good practice to do something in response, even simply logging the problem. For classes you design, only declare methods to throw exceptions where you want the caller to deal with a problem. If you want to ignore an exception, perhaps because of an automatic retry that happens every minute or two, simply place a comment in the catch block to explicitly say why the exceptional condition is ignored.

   // Better
try {
...
} catch (AnException ignored) {

// System automatically retries every minute
// Nothing to really do until retry

}

One very important practice related to exceptions thrown from methods is documentation. There is a javadoc tag for documenting which exceptions are thrown by a method. It's @throws. Best practices call for all checked exceptions to be documented. Common runtime exceptions should be documented too. For example, in the following method declaration, both the thrown exception and why the throwable exception could be thrown are documented. Don't just have the @throws ExceptionName bit. That doesn't add any more than the method declaration alone.

    /**
* Loads the class
*
* @param name
* Class name
*
* @return Resulting Class object
*
* @throws ClassNotFoundException
* If class not found
*/
public Class loadClass(String name)
throws ClassNotFoundException {
...
}

For runtime exceptions, an exception here is the parseInt method of Integer. This can throw a NumberFormatException (this is declared as part of the method declaration). However, because this is a RuntimeException, it doesn't have to be declared.

Not only don't runtime exceptions have to be declared, but neither do they have to be checked. For instance, every array access can throw an ArrayIndexOutOfBoundsException. It is not good practice to wrap all array access code within a try-catch block. Doing that makes code difficult to read and maintain.

   // This is bad, don't do it:
try {
for (int i=0, n=args.length; i

For recoverable conditions, it is good practice to have catch clauses with actions involved. These are typically checked exceptions, although it's also possible with runtime exceptions. Case in point: the previously mentioned parseInt method of Integer. If you are validating user input with the parseInt method, that is certainly a recoverable operation (assuming the user is still available).

While it is possible to create your own custom exceptions, more typically, you can reuse the system exception classes. These are usually sufficient for most needs, though not for every need.

Runtime exceptions that you might use include the following:

  • NullPointerException - Tends to be encountered more by accident than by design. If this commonly happens to you, you might think of peer reviews.

  • IllegalArgumentException - Often encountered when validating arguments to a method. In some cases, they might result from the typical explicit checks at the start of a method. In other cases, they could happen after various operations are performed. Subclasses include NumberFormatException and PatternSyntaxException (for regular expressions).

  • IndexOutOfBoundsException - The ArrayIndexOutOfBoundsException class is a subclass, so is StringIndexOutOfBoundsException. You can use these in your classes and methods to check for passing in an integer beyond the end (or before the beginning) of your data structure.

  • UnsupportedOperationException - Typically used by the Collections Framework to indicate that a requested operation is not supported. You can use it to indicate similar usage problems.

Reusing existing exception classes allows developers to keep their codebase smaller and also take advantage of the familiarity they have with the existing exception class hierarchy.

The final aspect of exception handling to explore is exception chaining. Introduced with the 1.4 release of the Java 2 Platform, Standard Edition, exception chaining allows you to attach the underlying cause of a problem to the thrown exception. Chaining is not usually meant for an end user to see. Instead, it allows the person debugging a problem to see what caused the underlying problem.

For instance, in the database world, specifically in the JDBC libraries, it is common to have catch clauses for SQLException. Even prior to exception chaining, the SQLException clause had a getNextException method which allowed chaining of exceptions. To find out all the underlying causes of the SQLException, you could have a loop that looks something like the following:

   try {

// JDBC code

} catch (SQLException ex) {

while (ex != null) {
System.err.println(
"SQLState: " + ex.getSQLState());
System.err.println(
"Message: " + ex.getMessage());
System.err.println(
"Vendor: " + ex.getErrorCode());
System.err.println("-----");
ex = ex.getNextException();
}
}

Instead of using the JDBC version of chaining, the standard approach is now the one shown below. Instead of printing the SQL State, message, and error code, just the exception type and message are displayed.

   try {

// Normal code

} catch (AnException ex) {

Throwable t = ex;
while (t != null) {
System.err.println(
"Type: " + t.getClass().getName());
System.err.println(
"Message: " + t.getMessage());
System.err.println("-----");
t = t.getCause();
}
}

There is certainly much more that can be done with exceptions. Hopefully, the practices shown here should help get you started toward better understanding and usage.

For additional information on exception handling, see Chapter 8 "Exceptions" in "Effective Java Programming Language Guide" by Joshua Bloch.

No comments:

Post a Comment

LinkWithin

Related Posts Plugin for WordPress, Blogger...