Giter Club home page Giter Club logo

throwable's Introduction

Throwable in Java

Description of the Repository

This repository is a workshop on Throwable in Java, mainly on its Exception subclass. It presents key points regarding that issue, relevant usage cases and specific application flows. Besides that there is an extended quiz (file questions.adoc stored in the root folder of the repository) to check the knowledge on Throwable in Java.

Run main methods in appropriate classes to see how Throwable types behave.

General Information about Exceptions

Exception in Programming in General

The exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program’s instructions. Throwable is Java implementation of an idea of an exception.

Exception Throwing

When an error occurs within a method, the method creates an object and hands it off to the runtime system. The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.

Exception Propagating

After a method throws an exception, the runtime system attempts to find something to handle it. The set of possible "somethings" to handle the exception is the ordered list of methods that had been called to get to the method where the error occurred. The list of methods is known as the call stack (see the next figure).

call stack
Figure 1. Call stack

The runtime system searches the call stack for a method that contains a block of code that can handle the exception. This block of code is called an exception handler. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called. When an appropriate handler is found, the runtime system passes the exception to the handler. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler.

The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches all the methods on the call stack without finding an appropriate exception handler, as shown in the next figure, the runtime system (and, consequently, the program) terminates.

Throwable

Throwable is a non-abstract, non-final super-class for Exceptions and Errors.

Throwable Hierarchy

tree
Figure 3. Throwable hierarchy

Throwable Types

Below some of the most common types of Throwable in Java are listed. Their usage examples are provided in the eu.ciechanowiec.throwable.throwableproducer package.

Exceptions

  1. FileNotFoundException

  2. ClassNotFoundException

  3. IOException

  4. ParseException

  5. InterruptedException

  6. RuntimeException:

    • ArithmeticException

    • NullPointerException

    • IndexOutOfBoundsException

    • IllegalArgumentException

    • IllegalStateException

    • ClassCastException

Errors

  1. StackOverflowError

  2. ExceptionInInitializerError

Mnemonics

Checked exceptions: C io P i N

Unchecked exceptions: A n i i C

Throwable Constructors

Throwable()
Throwable(String message)
Throwable(Throwable cause)
Throwable(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
Throwable(String message, Throwable cause)

Throwable Methods

Modifier and Type Method Description

final void

addSuppressed(Throwable exception)

Appends the specified exception to the exceptions that were suppressed in order to deliver this exception

Throwable

fillInStackTrace()

Fills in the execution stack trace

Throwable

getCause()

Returns the cause of this throwable or null if the cause is nonexistent or unknown

String

getLocalizedMessage()

Creates a localized description of this throwable

String

getMessage()

Returns the detail message string of this throwable

StackTraceElement[]

getStackTrace()

Provides programmatic access to the stack trace information printed by printStackTrace()

final Throwable[]

getSuppressed()

Returns an array containing all of the exceptions that were suppressed, typically by the try-with-resources statement, in order to deliver this exception

Throwable

initCause(Throwable cause)

Initializes the cause of this throwable to the specified value

void

printStackTrace()

Prints this throwable and its backtrace to the standard error stream

void

printStackTrace(PrintStream s)

Prints this throwable and its backtrace to the specified print stream

void

printStackTrace(PrintWriter s)

Prints this throwable and its backtrace to the specified print writer

void

setStackTrace(StackTraceElement[] stackTrace)

Sets the stack trace elements that will be returned by getStackTrace() and printed by printStackTrace() and related methods

String

toString()

Returns a short description of this throwable

athrow

Throwable and its subclasses (i.a. Error) can be thrown because during the compilation they are related with the athrow bytecode instruction (see Java Virtual Machine Specification at https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-2.html#jvms-2.10).

Key Points

Keywords

  • throws

  • try

  • catch

  • finally

  • throw

finally

  1. The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs (the unexpected exception is propagated to the caller).

  2. An exception thrown from the finally block is propagated to the caller as an exception thrown from the outside of the try-catch block; in such a case any unexpected exception thrown from the try block and propagated from there to the caller is suppressed by the exception thrown from the finally block.

  3. The finally block may not execute if the JVM exits while the try or catch code is being executed. For instance, if the System.exit(…​) command inside the try block is executed, the program immediately stops; even the finally block is not executed.

    • See eu.ciechanowiec.throwable.finally package.

Multicatching

  1. With inline catch blocks (exception variable is final then):

    try {
       throw new IndexOutOfBoundsException("Sample exception");
    } catch (IndexOutOfBoundsException | ArithmeticException exception) {
       Logger.error(exception);
    }
  2. With chained catch blocks:

    try {
       throw new IndexOutOfBoundsException("Sample exception");
    } catch (IndexOutOfBoundsException exception) {
       Logger.error(exception);
    } catch (RuntimeException exception) {
       Logger.error(exception);
    }
  3. Exceptions must be caught from the narrower to the broader one. Two same types of exceptions cannot be multicaught.

  4. In case of inline multicatch only one exception variable is possible.

  5. Types in the inline multicatch block must be disjoint (i.e. that one of them cannot be the subclass of the another one), so that for IndexOutOfBoundsException and RuntimeException there will be different responses in catch blocks. For that reason the following code will not compile:

    try {
        throw new IndexOutOfBoundsException("Sample exception");
    } catch (IndexOutOfBoundsException | RuntimeException exception) {
        Logger.error(exception);
    }
  6. Both Errors and Exceptions can be multicaught in the same block, both inline and chained.

  7. See eu.ciechanowiec.throwable.multicatch package.

try-with-resources

  1. Any object that implements AutoCloseable or Closeable can be used as a resource. Neither null nor other objects can be passed as a resource - the code will not compile.

  2. One or more resources can be declared in the try-with-resources block.

  3. There is no practical difference between AutoCloseable and Closeable (only historical: AutoCloseable was introduced later and Closeable extends AutoCloseable).

  4. To implement AutoCloseable or Closeable, the close() method must be implemented.

  5. If any, even unexpected, exception occurs, close() methods of all specified resources are called, which closes those resources.

  6. The resources are closed in the reverse order from which they were initialized.

  7. Resources must be final, in that:

    • a local variable declared in a resource specification is implicitly declared final if it is not explicitly declared final,

    • an existing variable referred to in a resource specification must be a final or effectively final variable that is definitely assigned before the try-with-resources statement, or a compile-time error occurs.

  8. It is possible to use bare try-with-resources block, without catch and finally block.

  9. An exception from the closing of one resource does not prevent the closing of other resources. Such an exception is added as a suppressed to the exception that occurred it the try block, regardless of whether the exception from the try block was or wasn’t caught. If there were no exception thrown from the try block, the exception that occurred during the closing of one of resources will not be suppressed and will be propagated to the caller.

  10. See eu.ciechanowiec.throwable.withresources package

Miscellaneous

  1. By convention, names of custom exceptions should end with -Exception suffix (e.g. ResourceNotFoundException). However, technically it is possible that the exception name will not follow this convention and, for instance, be named Object.

  2. If a checked exception is caught, then the code inside the try block must be able at least hypothetically produce the caught checked exception. This rule doesn’t apply to the unchecked exceptions. For that reason, the following code will not compile:

    try {
       System.out.println("This is a 'try block' without a checked exception");
       throw new IndexOutOfBoundsException("Unchecked exception");
    } catch (SQLException exception) {
       Logger.error(exception);
    }
  3. An exception thrown from the catch block is propagated to the caller as an exception thrown from the outside of the try-catch block. However, the finally block is executed anyway.

  4. The return statement inside the finally block will cause any unexpected exception that might be thrown in the try or catch block to be discarded and not propagated to the caller.

  5. The try-finally block, without the catch block, is possible, but the exception from the try block will be propagated to the caller.

  6. See eu.ciechanowiec.throwable.misc package

Handling Caught Exceptions

Below are some possibilities of how to handle caught exceptions. Some of listed actions can be mixed.

  1. Good practice:

    1. log the exception

    2. modify the caught exception (e.g. change the stack trace)

    3. perform some logic after catching the exception (e.g. remove the file created inside the try block)

    4. rethrow the caught exception

    5. chain exceptions, i.e. set the caught exception as the cause af a new one

  2. Bad practice:

    1. swallow the caught exception (do nothing)

    2. change the flow of the program

Mnemonics: Lo mo pe re ch || Swa ch

Checked vs Unchecked - Controversy

There is a controversy regarding the division of exceptions in Java on the checked and unchecked ones.

Arguments in Favour of the Division:

  • Checked exceptions thrown by critical methods force to handle them, which improves the program stability

  • Checked exceptions describe some behaviour of the method

Arguments Against the Division:

  • It is possible to develop robust software without checked exceptions (e.g. C++ and C don’t have such a concept)

  • Checked exceptions enforce the developer to handle them immediately, what can result in quickly and weakly provided exception handling

  • Checked exceptions violate the open/closed principle. If a checked exception is thrown from a method and the catch is three levels above, that exception must be declared in the signature of each method in the chain. It means that a change at a low level of the software can force signature changes on many higher levels

  • Checked exceptions break encapsulation because all functions in the path of a throw must know about details of that low-level exception.

Sources

Sources of knowledge on exceptions:

  1. D. Liang, Introduction to Java Programming and Data Structures, 2019, chapter 12.1-12.9, pp. 475-499

  2. Oracle tutorials on exceptions in Java:

  3. The Java Language Specification (ch. 11, ch. 14.20):

throwable's People

Contributors

ciechanowiec avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.