The course is part of this learning path
This training course introduces you to Java exceptions and how you should go about handling, managing, and recovering from them through the use of appropriate Java exception handling.
Learning Objectives
- Understand what exceptions are and when and how they happen
- How to handle and recover from exception
- Implement exception handling
- Understand the try catch finally statement
Prerequisites
- A basic understanding of software development
- A basic understanding of the software development life cycle
Intended Audience
- Software Engineers interested in learning Java to develop applications
- Software Architects interested in learning Java to design applications
- Anyone interested in basic Java application development and associated tooling
- Anyone interested in understanding the basics of the Java SDK
- Okay, welcome back. In this lecture we'll dive deeper into the implementation of exception handling within Java. We'll cover items such as, defining your own application exceptions. Automatic closure of resources. Suppressed exceptions. And handling multiple exceptions in one catch. Since exception is a class itself, we are able to subclass it to create our own exceptions to throw. This is usually done if there is an error or errors that you wish to inform the calling code about. Note that it is not a common practice to subclass neither error nor throwable. Constructors of exception classes. Standard exception classes define several constructors. The default constructor. A constructor accepting a detailed message about a problem. A constructor accepting an exception that caused the problem. And or, a constructor accepting a cause and detailed message. When defining custom excepting classes, you will most often redefine most of the constructors of its subclass. Designing and implementing exceptions. When defining your own exceptions, make sure the information about the cause of the exception is available within the exception itself. Developers should be able to retrieve details about the exception directly from the instance instead of having to parse the exception string to determine the name of the entity that caused the problem. Closure of resources. Many constructs in Java must be closed to release related resources. For example, JDBC constructs, I/O streams, sockets, etc. A resource must be closed even in exceptional circumstances. In general, resources that are open within an application must also be closed once the application is done with the resource. As long as the application follows the HEPIE flow, this generally not an issue but, as soon as an exception is thrown by the application, resources often end up remaining open. In the example shown here, the database connection will be closed when the statement is executed without causing problems. But, as soon as the execute method throws an exception, the close method is not invoked and the database connection as a resource remains open. Naturally, we could rely on the finally block to close the resource but, using the finally block introduces a whole number of new challenges.
The reference to the connection must be defined and initialized outside of the try block otherwise, the Java block scoping rules will not allow the reference to be used within the finally block. Since the sequel exception might also be thrown when the connection is requested the reference might still be null when the finally block is reached. So we will have to add another null pointer check to avoid a null pointer exception when trying to invoke the close method. Most close operations that have been defined on resources throw an exception which would have to be dealt with. As a result, developers often created helper methods to close the resource which would have to be called from within the finally block. With the introduction of Java 7, resources can be declared within the try block. These resources will automatically be closed by the runtime when the try block ceases to exist. Resources that implement the AutoClosable interface can be declared within the try-with-resources block. By doing so, the close method of the resource will be called by the runtime when the try block exists. Even though the close method of the AutoClosable interface declares to throw exception implementations of the interface are encouraged to throw more specific or specialized exception types. For example, the Java.sequel connection class implements this interface and throws an instance of sequel exception when things go wrong while closing the connection. Multiple auto closable types can be declared within the same try-with-resources block. These resources will be closed in the reverse order from which they were declared. However, it is not permissible to add any statements that do not result in an AutoClosable instance. Starting with Java 9, the AutoClosable types no longer need to be instantiated within the try-with-resources block. Instead, when AutoClosable types are referenced using final variables, these variables can be referenced within the try-with-resources block.
Suppressed exceptions. With the introduction of the try-with-resources block, a new challenge emerged. What should happen when the code in the try block throws an exception and calling the closed method on the AutoClosable instance also throws an exception? The runtime now has two exception instances to deal with. Which of these should be presented back to the client or caller? Java 7 adds methods to the throwable so that suppressed exceptions can be added and tracked. A suppressed exception is an exception that occurs when the close method is called on the AutoClosable instance after an exception was thrown previously from within the try block. The exception that was thrown from within the try block will be available to the client. The exception that was thrown by the close method and therefore suppressed will be added to the exception that is thrown to the client. When dealing with exceptions, it is not uncommon to have multiple catch blocks following a try block where each catch block deals with the exception in an identical way. In the example shown here, multiple catch blocks catch different specialized exceptions but end up throwing the same DAO exception. With the introduction of Java 7, you no longer need to define multiple catch blocks to catch multiple exceptions of different types. Multiple exception types can now be defined in the catch by separating them using the pipe symbol. When to use exceptions. Exceptions were designed to notify that some exceptional situation has occurred. Exceptions should never be used to control the flow of the application or as an alternative return value. Exception handling is a relatively expensive process. When an API provides methods to check the validity of a method call, do so before making it. You should try to prevent an exception from being thrown at all times. Instead of writing your own exception types for every exceptional situation, you might also want to take a look at the exception classes that already exist within the JDK. The APIs almost always define a standard set of exception classes that can be used. Okay, before we complete this lecture, consider the following questions to test yourself on the content that we have just reviewed. Okay, the answers to the above questions are, one, yes, you can extend exception on one of its subclasses. Two, no, only types that implement the AutoClosable interface. Three, when an exception is thrown from within a try-with-resources block this might result in another exception when the runtime tries to close the resource. Since Java can only throw a single exception the second exception will be suppressed. Okay, that completes this lecture. Go ahead and close it and we'll see you shortly in the next one.
Jeremy is a Content Lead Architect and DevOps SME here at Cloud Academy where he specializes in developing DevOps technical training documentation.
He has a strong background in software engineering, and has been coding with various languages, frameworks, and systems for the past 25+ years. In recent times, Jeremy has been focused on DevOps, Cloud (AWS, Azure, GCP), Security, Kubernetes, and Machine Learning.
Jeremy holds professional certifications for AWS, Azure, GCP, Terraform, Kubernetes (CKA, CKAD, CKS).