Skip to content

Commit e06ba5c

Browse files
Create exceptions concept and finish Calculator Conundrum concept exercise (exercism#2350)
* Bootstrap content for Exceptions concept * Source concept introduction from exercise * Update the concepts and prerequisites of exercise * Add link to Oracle docs * Rewrite concept introduction * Update about.md * Update Calculator Conundrum concept exercise * Set status of Calculator Conundrum to beta * Remove reference to `SimpleOperations` class from hints * Revert back to instance method as per track policy * Add links to docs in exercise hints * Remove `basics` as explicit prerequisite * Update concepts/exceptions/.meta/config.json Co-authored-by: Erik Schierboom <erik_schierboom@hotmail.com> * Introduce "throwing" and "catching" terms * Add 'exceptions as control flow' anti-pattern * Sync exercise introduction with concept --------- Co-authored-by: Erik Schierboom <erik_schierboom@hotmail.com>
1 parent a22d219 commit e06ba5c

17 files changed

Lines changed: 481 additions & 200 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"blurb": "Exceptions are thrown when an error that needs special handling occurs.",
3+
"authors": ["sanderploegsma"],
4+
"contributors": []
5+
}

concepts/exceptions/about.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
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
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Introduction
2+
3+
The Java programming language uses _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.
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, 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`, `catch` and `finally` 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+
```

concepts/exceptions/links.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"url": "https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html",
4+
"description": "Exceptions in Java"
5+
}
6+
]

config.json

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,13 @@
9090
"name": "Calculator Conundrum",
9191
"uuid": "9e62feec-c2c3-4fd6-94f5-0574cc65447d",
9292
"concepts": [
93-
"exception-handling"
93+
"exceptions"
9494
],
9595
"prerequisites": [
96-
"conditionals",
97-
"switch-case",
98-
"basics"
96+
"conditionals-if",
97+
"switch-statement"
9998
],
100-
"status": "wip"
99+
"status": "beta"
101100
},
102101
{
103102
"slug": "squeaky-clean",
@@ -1964,6 +1963,11 @@
19641963
"slug": "constructors",
19651964
"name": "Constructors"
19661965
},
1966+
{
1967+
"uuid": "b7f8e129-303c-45b8-ac07-297bfd5a9906",
1968+
"slug": "exceptions",
1969+
"name": "Exceptions"
1970+
},
19671971
{
19681972
"uuid": "3a1f7a96-b4a5-43d3-99e2-7c248e74e6c8",
19691973
"slug": "foreach-loops",

exercises/concept/calculator-conundrum/.docs/hints.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22

33
## 1. Implement the method calculate to support a few basic operations
44

5-
* Use a `switch-case` block to match different operations and implement them using the `SimpleOperation` class.
5+
- Use a [`switch` statement][switch-statement-docs] to match different operations.
66

77
## 2. Handle illegal operations
88

9+
- You cannot check for `null` inside a `switch` statement.
10+
- Use a `default` case for anything else at the end of the switch.
911

10-
* Check for `null` operations before the switch.
11-
* Add a case to the switch for the empty String.
12-
* Use a default for anything else at the end of the switch.
13-
* Throw an `IllegalOpertionException` with appropriate messages in different cases.
12+
## 3. Handle the exception thrown when dividing by zero
1413

15-
## 3. Handle the thrown DivideByZero exceptions
14+
- Use a [`try-catch` block][exception-handling-docs] to catch the `ArithmeticException` thrown when dividing by zero.
15+
- The `IllegalOperationException` class has a constructor that takes a message and a cause as its parameters.
1616

17-
* Use a `try-catch` block to catch `ArithmeticException`
18-
* Pass both the `message` and the `ArithmeticException` as the `cause` parameter when throwing the exception.
17+
[switch-statement-docs]: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
18+
[exception-handling-docs]: https://docs.oracle.com/javase/tutorial/essential/exceptions/handling.html

0 commit comments

Comments
 (0)