Which block is used to handle exceptions?
What is an Exception? Show
An exception is an “unwanted or unexpected event”, which occurs during the execution of the program i.e, at run-time, that disrupts the normal flow of the program’s instructions. When an exception occurs, the execution of the program gets terminated. Why does an Exception occur? An exception can occur due to several reasons like a Network connection problem, Bad input provided by a user, Opening a non-existing file in your program, etc Blocks & Keywords used for exception handling 1. try: The try block contains a set of statements where an exception can occur. try { // statement(s) that might cause exception }2. catch: The catch block is used to handle the uncertain condition of a try block. A try block is always followed by a catch block, which handles the exception that occurs in the associated try block. catch { // statement(s) that handle an exception // examples, closing a connection, closing // file, exiting the process after writing // details to a log file. }3. throw: The throw keyword is used to transfer control from the try block to the catch block. 4. throws: The throws keyword is used for exception handling without try & catch block. It specifies the exceptions that a method can throw to the caller and does not handle itself. 5. finally: It is executed after the catch block. We use it to put some common code (to be executed irrespective of whether an exception has occurred or not ) when there are multiple catch blocks. Example of an exception generated by the system is given below : Exception in thread "main" java.lang.ArithmeticException: divide by zero at ExceptionDemo.main(ExceptionDemo.java:5) ExceptionDemo: The class name main:The method name ExceptionDemo.java:The file name java:5:line numberJavaclass Division { public static void main(String[] args) { int a = 10, b = 5, c = 5, result; try { result = a / (b - c); System.out.println("result" + result); } catch (ArithmeticException e) { System.out.println("Exception caught:Division by zero"); } finally { System.out.println("I am in final block"); } } } Output: Exception caught:Division by zero I am in final blockAn example of throws keyword: Javaclass ThrowsExecp { static void fun() throws IllegalAccessException { System.out.println("Inside fun(). "); throw new IllegalAccessException("demo"); } public static void main(String args[]) { try { fun(); } catch (IllegalAccessException e) { System.out.println("caught in main."); } } } Output: Inside fun(). caught in main.Exception Handling in Java is a very interesting topic. An exception is an error event that can happen during the execution of a program and disrupts its normal flow. Java provides a robust and object-oriented way to handle exception scenarios known as Java Exception Handling. Why do we need Exception Handling?We don’t like exceptions but we always have to deal with them. The great news is that Exception handling in Java is extremely robust and easy to understand and use. Exceptions in java can arise from different kinds of situations such as wrong data entered by the user, hardware failure, network connection failure, Database server down, etc. The code that specifies what to do in specific exception scenarios is called exception handling. How Java Handles Exception?Java is an object-oriented programming language. So whenever an error occurs while executing a statement, it creates an exception object. The normal flow of the program halts and JRE tries to find someone that can handle the raised exception. The exception object contains a lot of debugging information such as method hierarchy, line number where the exception occurred, type of exception, etc. When the exception occurs in a method, the process of creating the exception object and handing it over to the runtime environment is called “throwing the exception”. Once runtime receives the exception object, it tries to find the handler for the exception. Exception Handler is the block of code that can process the exception object. The logic to find the exception handler is simple – starting the search in the method where the error occurred, if no appropriate handler found, then move to the caller method and so on. So if methods call stack is A->B->C and exception is raised in method C, then the search for the appropriate handler will move from C->B->A. If an appropriate exception handler is found, the exception object is passed to the handler to process it. The handler is said to be “catching the exception”. If there is no appropriate exception handler found then the program terminates and prints information about the exception to the console. Java Exception handling framework is used to handle runtime errors only. The compile-time errors have to be fixed by the developer writing the code else the program won’t execute. Java Exception Handling KeywordsJava provides specific keywords for exception handling purposes.
Exception Handling Example Programpackage com.journaldev.exceptions; import java.io.FileNotFoundException; import java.io.IOException; public class ExceptionHandling { public static void main(String[] args) throws FileNotFoundException, IOException { try{ testException(-5); testException(-10); }catch(FileNotFoundException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); }finally{ System.out.println("Releasing resources"); } testException(15); } public static void testException(int i) throws FileNotFoundException, IOException{ if(i < 0){ FileNotFoundException myException = new FileNotFoundException("Negative Integer "+i); throw myException; }else if(i > 10){ throw new IOException("Only supported for index 0 to 10"); } } }Output: The testException() method is throwing exceptions using the throw keyword. The method signature uses the throws keyword to let the caller know the type of exceptions it might throw. In the main() method, I am handling exceptions using the try-catch block in the main() method. When I am not handling it, I am propagating it to runtime with the throws clause in the main method. The testException(-10) never gets executed because of the exception and then the finally block is executed. The printStackTrace() is one of the useful methods in the Exception class for debugging purposes. Some important points to note:
Java Exception HierarchyAs stated earlier, when an exception is raised an exception object is getting created. Java Exceptions are hierarchical and inheritance is used to categorize different types of exceptions. Throwable is the parent class of Java Exceptions Hierarchy and it has two child objects – Error and Exception. Exceptions are further divided into checked exceptions and runtime exceptions.
Some useful methods of Exception ClassesJava Exception and all of its subclasses don’t provide any specific methods and all of the methods are defined in the base class - Throwable. The exception classes are created to specify different kinds of exception scenarios so that we can easily identify the root cause and handle the exception according to its type. The Throwable class implements the Serializable interface for interoperability. Some of the useful methods of Throwable class are;
Java 7 Automatic Resource Management and Catch block improvementsIf you are catching a lot of exceptions in a single try block, you will notice that the catch block code looks very ugly and mostly consists of redundant code to log the error. Java 7 one of the feature was improved catch block where we can catch multiple exceptions in a single catch block. The catch block with this feature looks like below: catch(IOException | SQLException ex){ logger.error(ex); throw new MyException(ex.getMessage()); }There are some constraints such as the exception object is final and we can’t modify it inside the catch block, read the full analysis at Java 7 Catch Block Improvements. Most of the time, we use finally block just to close the resources. Sometimes we forget to close them and get runtime exceptions when the resources are exhausted. These exceptions are hard to debug and we might need to look into each place where we are using that resource to make sure we are closing it. Java 7 one of the improvements was try-with-resources where we can create a resource in the try statement itself and use it inside the try-catch block. When the execution comes out of the try-catch block, the runtime environment automatically closes these resources. Sample of the try-catch block with this improvement is: try (MyResource mr = new MyResource()) { System.out.println("MyResource created in try-with-resources"); } catch (Exception e) { e.printStackTrace(); }Read a detailed explanation of this feature at Java 7 Automatic Resource Management. How to Create Custom Exception Class in Java?Java provides a lot of exception classes for us to use but sometimes we may need to create our own custom exception classes. For example, to notify the caller about a specific type of exception with the appropriate message. We can have custom fields for tracking, such as error codes. For example, let’s say we write a method to process only text files, so we can provide the caller with the appropriate error code when some other type of file is sent as input. Here is an example of custom exception class and showing its usage. package com.journaldev.exceptions; public class MyException extends Exception { private static final long serialVersionUID = 4664456874499611218L; private String errorCode="Unknown_Exception"; public MyException(String message, String errorCode){ super(message); this.errorCode=errorCode; } public String getErrorCode(){ return this.errorCode; } } package com.journaldev.exceptions; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class CustomExceptionExample { public static void main(String[] args) throws MyException { try { processFile("file.txt"); } catch (MyException e) { processErrorCodes(e); } } private static void processErrorCodes(MyException e) throws MyException { switch(e.getErrorCode()){ case "BAD_FILE_TYPE": System.out.println("Bad File Type, notify user"); throw e; case "FILE_NOT_FOUND_EXCEPTION": System.out.println("File Not Found, notify user"); throw e; case "FILE_CLOSE_EXCEPTION": System.out.println("File Close failed, just log it."); break; default: System.out.println("Unknown exception occured, lets log it for further debugging."+e.getMessage()); e.printStackTrace(); } } private static void processFile(String file) throws MyException { InputStream fis = null; try { fis = new FileInputStream(file); } catch (FileNotFoundException e) { throw new MyException(e.getMessage(),"FILE_NOT_FOUND_EXCEPTION"); }finally{ try { if(fis !=null)fis.close(); } catch (IOException e) { throw new MyException(e.getMessage(),"FILE_CLOSE_EXCEPTION"); } } } }We can have a separate method to process different types of error codes that we get from different methods. Some of them get consumed because we might not want to notify the user of that, or some of them we will throwback to notify the user of the problem. Here I am extending Exception so that whenever this exception is being produced, it has to be handled in the method or returned to the caller program. If we extend RuntimeException, there is no need to specify it in the throws clause. This is a design decision but I always like checked exceptions because I know what exceptions I can get when calling any method and take appropriate action to handle them. Best Practices for Exception Handling in Java
While debugging we will have to look out at the stack trace carefully to identify the actual location of exception. If we change our implementation logic to check for these exceptions early as below: private static void processFile(String file) throws MyException { if(file == null) throw new MyException("File name can't be null", "NULL_FILE_NAME"); //further processing }Then the exception stack trace will be like below that clearly shows where the exception has occurred with clear message. com.journaldev.exceptions.MyException: File name can't be null at com.journaldev.exceptions.CustomExceptionExample.processFile(CustomExceptionExample.java:37) at com.journaldev.exceptions.CustomExceptionExample.main(CustomExceptionExample.java:12)
Which is used to handle the exceptions in Java?Java Exception Handling Keywords
Sometimes we might want to generate exceptions explicitly in our code, for example in a user authentication program we should throw exceptions to clients if the password is null. The throw keyword is used to throw exceptions to the runtime to handle it.
Which class is used to handle exceptions?Exception Hierarchy
All exception and error types are subclasses of class Throwable, which is the base class of the hierarchy. One branch is headed by Exception. This class is used for exceptional conditions that user programs should catch.
|