Written by:
David VlijmincxIntroduction
Using try-catch blocks and exceptions, you can handle failures that occur during runtime. While some methods require explicit exception
handling, others can be handled differently.
Creating Methods that Throw Exceptions
Methods that can throw checked exceptions must declare this using the throws
keyword. The following example shows two methods
one that doesn't declare and exception but can still throw a runtime exception. The other method declares a checked exception.
The user of that method needs to handle it.
1
2
3
4
5
6
7
| public void update(String name, String userId) {
// This method doesn't declare any exceptions
}
public void update(String name, String userId) throws Exception {
// This method declares it can throw a SQLException
}
|
When calling a method that throws a checked exception, you'll get a compilation error if you don't handle it:
1
2
3
4
5
6
7
8
9
| // This won't compile without exception handling
update("John Doe", "USER123");
// This will compile and work
try {
update("John Doe", "USER123");
} catch (Exception e) {
// Handle the exception
}
|
Throwing Exceptions inside Constructors
Constructors can throw exceptions, which is useful for validating object during creation. Here's an example that validates a username during object instantiation:
1
2
3
4
5
6
7
8
9
10
11
12
13
| class User {
String name;
public User(String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Name cannot be null or empty");
}
this.name = name;
}
}
|
Basic Exception Handling with Try-Catch
The standard way to handle exceptions in Java is using try-catch blocks. The following example shows you how to use the try statement.
1
2
3
4
5
| try{
new User("name");
} catch (Exception e) {
System.out.println("e.getMessage() = " + e.getMessage());
}
|
Handling Specific Exception Types
You can catch different types of exceptions separately. This approach is useful when a method might throw multiple
exception types. Here's an implementation where the User constructor could throw both IllegalArgumentException and ValidationException exceptions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| static class ValidationException extends RuntimeException {}
class User {
String name;
public User(String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Name cannot be null or empty");
}
if (name.length() > 20) {
throw new ValidationException();
}
this.name = name;
}
}
public void main(String[] args) {
try{
new User("name");
} catch (IllegalArgumentException e) {
System.out.println("e.getMessage() = " + e.getMessage());
} catch (ValidationException e) {
System.out.println("e.getMessage() = other message" + e.getMessage());
}
}
|
Combining catch statements
If the exception handling is the same for two or more exceptions you can use a pipe to combine these catch statements.
The following example shows you how to improve the previous error handling.
1
2
3
4
5
| try{
new User("name");
} catch (IllegalArgumentException | ValidationException e) {
System.out.println("e.getMessage() = " + e.getMessage());
}
|
Using Optional to Avoid using Exceptions
In some cases you can prevent having to use exceptions. For example when looking for a user you could use Optional to
know if a user was found or not.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| public static void main(String[] args) {
UserService userService = new UserService();
userService.findUserSafely("USER123")
.ifPresent(user -> System.out.println("name"));
}
public class UserService {
public Optional<User> findUserSafely(String userId) {
try {
User user = findUser(userId);
return Optional.of(user);
} catch (IllegalStateException e) {
return Optional.empty();
}
}
}
|
Using RuntimeExceptions for Unchecked Exceptions
When you want to throw exceptions without forcing the caller to handle them, use RuntimeException. You also don't have to declare
them in the signature of the method. So other developers won't immediately know that the method throws an exception. This is how you throw a
runtime exception:
1
2
3
4
5
6
7
| public User getUser(String userId) {
if (userId == null) {
throw new RuntimeException("UserId cannot be null");
}
// ... your code
}
|