|
| 1 | +# About |
| 2 | + |
| 3 | +The Java programming language uses [_exceptions_][exceptions] to handle errors and other exceptional events. |
| 4 | + |
| 5 | +## What is an exception |
| 6 | + |
| 7 | +An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. |
| 8 | +Exceptions are raised explicitly in Java, and the act of raising an exception is called _throwing an exception_. |
| 9 | +The act of handling an exception is called _catching an exception_. |
| 10 | + |
| 11 | +Java distinguishes three types of exceptions: |
| 12 | + |
| 13 | +1. Checked exceptions |
| 14 | +2. Unchecked exceptions |
| 15 | +3. Errors |
| 16 | + |
| 17 | +### Checked exceptions |
| 18 | + |
| 19 | +_Checked exceptions_ are exceptional conditions that an application should anticipate and recover from. |
| 20 | +An example of a checked exception is the `FileNotFoundException` which occurs when a method is trying to read a file that does not exist. |
| 21 | + |
| 22 | +This type of exception is checked at compile-time: methods that throw checked exceptions should specify this in their method signature, and code calling a method that might throw a checked exception is required to handle it or the code will not compile. |
| 23 | + |
| 24 | +All exceptions in Java that do not inherit from `RuntimeException` or `Error` are considered checked exceptions. |
| 25 | + |
| 26 | +### Unchecked exceptions |
| 27 | + |
| 28 | +_Unchecked exceptions_ are exceptional conditions that an application usually cannot anticipate or recover from. |
| 29 | +An example of an unchecked exception is the `NullPointerException` which occurs when a method that is expecting a non-null value but receives `null`. |
| 30 | + |
| 31 | +This type of exception is not checked at compile-time: methods that throw unchecked exceptions are not required to specify this in their method signature, and code calling a method that might throw an unchecked exception is not required to handle it. |
| 32 | + |
| 33 | +All exceptions in Java that inherit from `RuntimeException` are considered unchecked exceptions. |
| 34 | + |
| 35 | +### Errors |
| 36 | + |
| 37 | +_Errors_ are exceptional conditions that are external to an application. |
| 38 | +An example of an error is the `OutOfMemoryError` which occurs when an application is trying to use more memory than is available on the system. |
| 39 | + |
| 40 | +Like unchecked exceptions, errors are not checked at compile-time. They are not usually thrown from application code. |
| 41 | + |
| 42 | +All exceptions in Java that inherit from `Error` are considered errors. |
| 43 | + |
| 44 | +## Throwing exceptions |
| 45 | + |
| 46 | +A method in Java can throw an exception by using the [`throw` statement][throw-statement]. |
| 47 | + |
| 48 | +### Throwing a checked exception |
| 49 | + |
| 50 | +When throwing a checked exception from a method, it is required to specify this in the method signature by using the [`throws` keyword][throws-keyword], as shown in the example below. |
| 51 | +This forces calling code to anticipate that an exception might be thrown and handle it accordingly. |
| 52 | + |
| 53 | +```java |
| 54 | +public class InsufficientBalanceException extends Exception { |
| 55 | + |
| 56 | +} |
| 57 | + |
| 58 | +public class BankAccount { |
| 59 | + public void withdraw(double amount) throws InsufficientBalanceException { |
| 60 | + if (balance < amount) { |
| 61 | + throw new InsufficientBalanceException(); |
| 62 | + } |
| 63 | + |
| 64 | + // rest of the method implementation |
| 65 | + } |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +### Throwing an unchecked exception |
| 70 | + |
| 71 | +When throwing an unchecked exception from a method, it is not required to specify this in the method signature - although it is supported. |
| 72 | + |
| 73 | +```java |
| 74 | +public class BankAccount { |
| 75 | + public void withdraw(double amount) { |
| 76 | + if (amount < 0) { |
| 77 | + throw new IllegalArgumentException("Cannot withdraw a negative amount"); |
| 78 | + } |
| 79 | + |
| 80 | + // rest of the method implementation |
| 81 | + } |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +## Handling exceptions |
| 86 | + |
| 87 | +Handling exceptions in Java is done with the [`try`][try-block], [`catch`][catch-block] and [`finally`][finally-block] keywords. |
| 88 | + |
| 89 | +- Code statements that might throw an exception should be wrapped in a `try` block. |
| 90 | +- The `try` block is followed by one or more `catch` blocks that catch the exceptions thrown in the `try` block. |
| 91 | +- The `catch` blocks are optionally followed by a `finally` block that always executes after the `try` block, regardless of whether an exception was thrown or not. |
| 92 | + |
| 93 | +The following example shows how these keywords work: |
| 94 | + |
| 95 | +```java |
| 96 | +public class ATM { |
| 97 | + public void withdraw(BankAccount bankAccount, double amount) { |
| 98 | + try { |
| 99 | + System.out.println("Withdrawing " + amount); |
| 100 | + bankAccount.withdraw(amount); |
| 101 | + System.out.println("Withdrawal succeeded"); |
| 102 | + } catch (InsufficientBalanceException) { |
| 103 | + System.out.println("Withdrawal failed: insufficient balance"); |
| 104 | + } catch (RuntimeException e) { |
| 105 | + System.out.println("Withdrawal failed: " + e.getMessage()); |
| 106 | + } finally { |
| 107 | + System.out.println("Current balance: " + bankAccount.getBalance()); |
| 108 | + } |
| 109 | + } |
| 110 | +} |
| 111 | +``` |
| 112 | + |
| 113 | +In this example, when no exception is thrown, the following is printed: |
| 114 | + |
| 115 | +``` |
| 116 | +Withdrawing 10.0 |
| 117 | +Withdrawal succeeded |
| 118 | +Current balance: 5.0 |
| 119 | +``` |
| 120 | + |
| 121 | +However, should the `bankAccount.withdraw(amount)` statement throw an `InsufficientBalanceException`, the following is printed: |
| 122 | + |
| 123 | +``` |
| 124 | +Withdrawing 10.0 |
| 125 | +Withdrawal failed: insufficient balance |
| 126 | +Current balance: 5.0 |
| 127 | +``` |
| 128 | + |
| 129 | +Or, in case an unchecked exception is thrown by the `bankAccount.withdraw(amount)`, the following is printed: |
| 130 | + |
| 131 | +``` |
| 132 | +Withdrawing -10.0 |
| 133 | +Withdrawal failed: Cannot withdraw a negative amount |
| 134 | +Current balance: 5.0 |
| 135 | +``` |
| 136 | + |
| 137 | +## When not to use exceptions |
| 138 | + |
| 139 | +As stated previously, exceptions are events that disrupt the normal flow of instructions, and are used to handle _exceptional events_. |
| 140 | +It is therefore [not recommended to use exceptions for flow control][dont-use-exceptions-for-flow-control] in your application. |
| 141 | + |
| 142 | +[exceptions]: https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html |
| 143 | +[throw-statement]: https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html |
| 144 | +[try-block]: https://docs.oracle.com/javase/tutorial/essential/exceptions/try.html |
| 145 | +[catch-block]: https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html |
| 146 | +[finally-block]: https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html |
| 147 | +[throws-keyword]: https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html |
| 148 | +[dont-use-exceptions-for-flow-control]: https://web.archive.org/web/20140430044213/http://c2.com/cgi-bin/wiki?DontUseExceptionsForFlowControl |
0 commit comments