Java / Exception
When an exception occurs, the execution of the program is aborted and handed over to an appropriate exception handler. The try-catch-finally block is used to handle the exception.
The code in which the exception may occur is enclosed in a try block ,also called as guarded region.
The catch clause matches a specific exception to a block of code which handles that exception.
The finally block executes even no exception occurs and usually hold clean up code such are closing database connection, file etc.
An error is an irrecoverable condition occurring at runtime, for example, OutOfMemory error. These JVM errors can not be fixed at runtime. Though an error can be caught in catch block, the execution of application will halt as errors are not recoverable.
An Exception could be handled by using either try-catch block or throwing exception back to caller.
In Java, there are two types of exceptions.
Checked exceptions : Exceptions that inherit from the Exception class are checked exceptions. Client code has to handle the checked exceptions thrown by the API, either in a catch clause or by forwarding it outward with the throws clause. Examples ? SQLException, IOxception.
Unchecked exceptions : RuntimeException also extends from Exception. However, all of the exceptions that inherit from RuntimeException get special treatment. There is no requirement for the client code to deal with them, and hence they are called unchecked exceptions. Example Unchecked exceptions are NullPointerException, OutOfMemoryError, DivideByZeroException typically, programming errors.
Using multiple catch blocks we may specify multiples exception to be handled in Java. For example, the below code handles both IOException and SQLException.
catch (IOException ioEx) { logger.log(ioEx); throw ioEx; catch (SQLException sqlEx) { logger.log(sqlEx); throw sqlEx; }
Although the above code handles multiple exceptions, we could notice that both blocks has same code and handling multiple exception sometimes lead to code duplication. Also in releases prior to Java 7, it is difficult to create a common method to eliminate the duplicated code because the exception variable has different types.
In Java SE 7 and later, multiple exception by a single catch block is introduced. This feature eliminates code duplication and reduce the possiblity to catch an overly broad exception.
The following example, which will execute in Java SE 7 and later, eliminates the duplicate code.
catch (IOException|SQLException exception) { logger.log(exception); throw exception; }
The catch clause specifies the types of exceptions that each block can handle, and each exception type is separated with a pipe delimiter (|).
Note that if a catch block handles more than one exception type, then the catch parameter is implicitly final i.e. the exception variable value cannot be changed within the catch block.
The new exception thrown at a catch or finally block will propagate out of that block, resulting the current exception be aborted or ignored as the new exception is propagated outward.
The new exception starts unwinding up the stack as ususal just like any other exceptions, stepping out of the current block (the catch or finally block) and subject to any applicable catch or finally blocks along the way.
One of the desired approaches is handling the exception of catch or finally block within the same block itself.
Yes. Finally clause is executed even when an exception is thrown from anywhere in either try or catch block. See the below example.
package net.javapedia.exceptions; import java.io.IOException; public class FinallyException { public static void main(String[] args) throws IOException { try { System.out.println("javapedia.net: printed from try block."); throw new Exception(); } catch (Exception e) { System.out.println("javapedia.net: printed from catch block."); throw new IOException(); } finally { System.out.println("javapedia.net: printed from Finally clause."); } } }
User-defined exceptions can be implemented by,
- defining a class to respond to an exception and
- embedding a throw statement in the try clause where the exception can occur or declaring that the method to throw the exception to invoking method where it is handled.
A new exception can be defined by deriving it from the Exception class as follows.
public class UserDefinedException extends Exception { public UserDefinedException() { super(); } public UserDefinedException(String errorMessage) { super(errorMessage); } }
The throw statement is used to signal the occurance of the exception within a try block. Often, exceptions are instantiated in the same statement in which they are thrown using the syntax.
throw new UserDefinedException ("throwing User defined Exception.")
To handle the exception within the method where it is thrown, a catch statement that handles UserDefinedException, must follow the try block. If the developer does not want to handle the exception in the method itself, the method must pass the exception using the syntax:
public myMethodName() throws UserDefinedException
If the custom exception needs to be unchecked, then have the user defined exception class extend RuntimeException.
public class UserDefinedException extends RuntimeException { UserDefinedException(String msg) { super(msg); } }
The Exception object will be garbage collected in the next garbage collection process.
A finally block will be executed whether or not an exception is thrown and is used to release those resources held by the application.
Finalize is a protected method of the Object class, which is called by the Java Virtual Machine (JVM) just before an object is garbage collected.
If the JVM exits while the try or catch code is being executed, then the finally block may not execute. System.exit cause the finally block to not execute.
If the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
Yes. The return statement executes the finally block.
public class FinallyReturn { public static void main(String[] args) { System.out.println("Value returned = " + myMethod()); } public static int myMethod() { try { return 0; } finally { return 1; } } }
Output: Value returned = 1
The try block needs to be followed by either catch or finally block or both. Any exception thrown from a try block needs to be either caught in the catch block or else any specific tasks to be performed are placed in the finally block. The exceptions that are likely to be thrown should be declared in the throws clause of the method.
Java finally block is used to execute important code such as closing connection, stream and files.
Java finally block is always executed whether exception is handled or not. Java finally block follows try or catch block.
Exception is an abnormal condition which occurs during the execution of a program and disrupts normal flow of the program. This exception must be handled properly. If it is not handled, program will be terminated abruptly.
We can group only un-related exceptions together. It is illegal to group exceptions which has parent-child relationship. For example, it is illegal to write a multi-catch statement like this:
try { ... } catch (FileNotFoundException | IOException ex) { System.err.println("File not found."); }
FileNotFoundException is a subclass of IOException so this grouping is invalid and the compiler reports a problem that "error: Alternatives in a multi-catch statement cannot be related by subclassing".
The try-with-resources statement is a try statement that declares one or more resources, where resources are objects that must be closed and try-with-resources statement ensures that each resource is closed at the end of the statement.
This statement is introduced in Java 7.
Yes. We can use multiple resources inside a try-with-resources block and have them all automatically closed.
The resources will be closed in reverse order of the order in which they are created / listed inside the parentheses in try statement.
- Minimize lines of code,
- Automatic resource management,
- No need of finally block just to close the resources,
- Manage multiple resources.
A resource is closed only if it is initialized to a non-null value. If the reference is null, no attempt is made to call close() on it, no NullPointerException is thrown, and it works as expected.
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.
The throw clause explicitly throw as an exception while throws clause intimate the compiler that exceptions are being handled and this method might throw.
The throws need to be used in the methods definition and also while invoking the method that raises checked exceptions.
No, The try block must be followed by either catch or finally block and only try block results in compile time error.
In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.
In case of multiple resources, the close methods of resources are called in the opposite order of their creation.
Exception chaining is the technique of handling exceptions by re-throwing a caught exception after wrapping it inside a new exception. This is very helpful in wrapping unchecked exceptions into a checked exception. The entire trace of errors is captured in the stacktrace of the exception.
The below constructors of Throwable class support chained exceptions in java :
-
Throwable(Throwable cause)
, cause is the exception that causes the current exception. Throwable(String msg, Throwable cause)
, where msg is the exception message and cause is the exception that causes the current exception.
The below methods support chained exception.
-
getCause()
method :- This method returns actual cause of an exception. -
initCause(Throwable cause)
method :- This method sets the cause for the calling exception.
The following example shows how to use a chained exception.
try { } catch (IOException e) { throw new AnotherWrappedSampleException("Other IOException", e); }
In this example, when an IOException is caught, a new AnotherWrappedSampleException exception is created with the original cause attached and the chain of exceptions is thrown up to the next higher level exception handler.
A stack trace provides information on the execution history of the current thread and lists the names of the classes and methods that were called at the point when the exception occurred.
A stack trace is a useful debugging tool that you'll normally take advantage of when an exception has been thrown.
When you are handling multiple catch blocks, make sure that you are specifing exception sub classes first, then followed by exception super classes. Otherwise we will get compile time error.
In Java7, try-with-resources syntax needed a fresh variable to be declared for each resource being managed by the statement. Java9 has improved this statement by eliminating the need of new variable to be created.
FileOutputStream fileOutputStream = new FileOutputStream("/file.txt"); try(FileOutputStream fileOutputStream=fileOutputStream){ //do some operation } // Everytime we need to create new variable in Java 7
// Java 9 FileOutputStream fileOutputStream = new FileOutputStream("/file.txt"); try(fileOutputStream){ //do some operation }
We can have an empty catch block but its a bad practice. Never have an empty catch block as if the exception is caught by that block, we will have no information about the exception and it wil be difficult to debug it. There should be at least a logging statement to log the exception details in log files.
No. You will get compile time exception, "The exception FileNotFoundException is already caught by the alternative IOException". This is because FileNotFoundException is a subclass of IOException. To fix it, use single catch statements for these exceptions.
Exception and all its subclasses doesnt provide any specific methods and all of the methods are defined in the base class Throwable.
- String getMessage() This method returns the message String of Throwable and the message can be provided while creating the exception through its constructor.
- String getLocalizedMessage() This method is provided so that subclasses can override it to provide locale specific message to the calling program. Throwable class implementation of this method simply use getMessage() method to return the exception message.
- synchronized Throwable getCause() This method returns the cause of the exception or null id the cause is unknown.
- String toString() This method returns the information about Throwable in String format, the returned String contains the name of Throwable class and localized message.
- void printStackTrace() This method prints the stack trace information to the standard error stream, this method is overloaded and we can pass PrintStream or PrintWriter as argument to write the stack trace information to the file or stream.
If the exception type is not represented by existing Exception in the Java platform, or if you need to provide more information to client code to treat it in a more precise manner, then you should create a custom exception.
Deciding whether a custom exception should be checked or unchecked depends entirely on the business case. However, as a rule of thumb; if the code using your exception can be expected to recover from it, then create a checked exception otherwise make it unchecked.
Also, you should inherit from the most specific Exception subclass that closely relates to the one you want to throw. If there is no such class, then choose Exception as the parent.
Yes, it can be handled as the same way as exception. However it is not a good idea to handle it.
Yes. However, it should not be caught as it is a bad practice.
The checked exceptions are ClassNotFoundException, SQLException, IOException and FileNotFoundException.
The unchecked exception include NullPointerException, ArrayIndexOutOfBoundsException, NumberFormatException and RuntimeException.
OutOfMemoryError is a sub class of java.lang.Error
which occurs when JVM runs out of memory.
StackOverflowError is a subclass of java.lang.Error
which is thrown by the JVM when stack overflows.
Overriding method cannot throw higher Exception than the overridden method. If the original method throws IOException then the overriding method cannot throw superclass of IOException, I.e., Exception but it can throw any subclass of IOException or does not throw any Exception at all.
This rule only applies to only checked Exception, overridden method is free to throw any unchecked Exception.
Yes, in case of unchecked exception, overridden method can throw.
No, we cannot. They form a single unit.
try { // Statements that may raise exceptions } // No statement allowed here catch(Exception ex) { //Catching the exceptions here } // No statement allowed here finally { // This block is always executed }
No, It results compilation error. The try block must be followed by either catch or finally block.
The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or its subclass) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement. Similarly, only this class or one of its subclasses can be the argument type in a catch clause.
A throwable contains a snapshot of the execution stack of its thread at the time it was created. It can also contain a message string that gives more information about the error. It also can contain a cause : another throwable that caused this throwable to get thrown.
final keyword is used to make a variable or a method or a class as "unchangeable".
Final variable: A variable which is declared as final, its value cannot be changed once it is initialized.
class FinalKeywordExample { public static void main(String[] args) { final int x = 10; x = 200;// Compile Time Error } }
A final method declared as final can not be overridden or modified in the subclass.
class Parent { final void parentMethod() { } } class Child extends Parent { //Compilation error public void parentMethod() { } }
A final class cannot be extended.
final class Parent { void parentMethod() { } } //Compilation error class Child extends Parent { }
finally block is used for exception handling along with try and catch blocks. finally block is always executed whether an exception is raised or not and raised exception is handled or not. Most of the time, this block is used to close the resources like database connection, I/O resources.
try { // do stuff } catch { // handle errors } finally { // clean up connections etc. }
finalize method is a protected method of java.lang.Object class. It is inherited by every class you create in Java. This method is called by garbage collector thread before an object is removed from the memory. finalize() method is used to perform some cleanup operations on an object before it is removed from the memory.
public class FinalizeTest { public static void main(String[] args) throws Throwable { FinalizeTest fTest = new FinalizeTest(); FinalizeTest fTest2 = new FinalizeTest(); fTest = null; fTest2 = null; System.gc(); System.out.println("Main Thread complete."); } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("finalize method overriden"); } }
Exceptions that raised in the try block are handled in the catch block. If it is unable to handle that exception, it can re-throw that exception using throw keyword. It is called re-throwing an exception.
try { String s = null; System.out.println(s.equals(hello)); //This statement throws NullPointerException } catch (NullPointerException ex) { System.out.println("NullPointerException is caught."); throw ex; //Re-throwing NullPointerException }
Broadly there are 2 rules.
If superclass method has not declared any exception using throws clause then subclass overridden method cannot declare any checked exception though it can declare unchecked exception.
If superclass method has declared an exception using throws clause then subclass overridden method can do one of the following.
- sub-class can declare the same exception as declared in the super-class method.
- subclass can declare the subtype exception of the exception declared in the superclass method. But subclass method can not declare any exception that is up in the hierarchy than the exception declared in the super class method.
- subclass method can choose not to declare any exception at all.
- Exception in thread thread_name: java.lang.OutOfMemoryError: Java heap space.
- java.lang.OutOfMemoryError: GC Overhead limit exceeded.
- java.lang.OutOfMemoryError: Requested array size exceeds VM limit.
- java.lang.OutOfMemoryError: Metaspace.
- java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?
- java.lang.OutOfMemoryError: Compressed class space.
- java.lang.OutOfMemoryError: reason stack_trace_with_native_method.
JProbe, JHat and OptimizeIt.
It is strongly advised to not have the close method throw InterruptedException. This exception interacts with a thread's interrupted status, and runtime misbehavior is likely to occur if an InterruptedException is suppressed. More generally, if it would cause problems for an exception to be suppressed, the AutoCloseable.close method should not throw it.
Closeable interface.
Closeable extends AutoCloseable and both are interfaces. Closeable throws IOException and AutoCloseable throws Exception.
Exceptions are immutable and its message cannot be altered after they've been created. Try the below code snippet.
throw new Exception("Custom exception: " + messageId, originalException);