Exception Handling - Part 2 (Handling Exceptions)
Handling Exceptions:-
---------------------------------------
--> throws:-
The simplest way to “handle” an exception is to rethrow it:
E.g.:-
public int getPlayerScore(String playerFile) throws FileNotFoundException {
Scanner contents = new Scanner(new File(playerFile));
return Integer.parseInt(contents.nextLine());
}
Because FileNotFoundException is a checked exception, this is the simplest way to satisfy the compiler, but it does mean that anyone that calls our method now needs to handle it too.
parseInt can throw a NumberFormatException, but because it is unchecked, we aren't required to handle it.
--> try-catch:-
If we want to handle the exception ourselves, whether it can be Checked or Unchecked, we need to use try-catch block.
E.g.:-
public int getPlayerScore(String playerFile) {
try {
Scanner contents = new Scanner(new File(playerFile));
return Integer.parseInt(contents.nextLine());
} catch (FileNotFoundException noFile) {
throw new IllegalArgumentException("File not found");
}
}
--> finally:-
Now, there are times when we have code that needs to execute regardless of whether an exception occurs, and this is where the finally keyword comes in.
E.g.:-
public int getPlayerScore(String filePath) throws FileNotFoundException {
Scanner contents = null;
try {
contents = new Scanner(new File(filePath));
return Integer.parseInt(contents.nextLine());
} finally {
try{
if (contents != null) {
contents.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
Here, the finally block indicates what code we want Java to run regardless of what happens with trying to read the file.
领英推荐
Even if a FileNotFoundException is thrown up the call stack, Java will call the contents of finally before doing that.
--> try-with-resources:-
As of Java 7, we can simplify the above code when working with things that extend AutoCloseable.
E.g.:-
public int getPlayerScore(String playerFile) {
try (Scanner contents = new Scanner(new File(playerFile))) {
return Integer.parseInt(contents.nextLine());
} catch (FileNotFoundException e ) {
logger.warn("File not found, resetting score.");
return 0;
}
}
When we place references that are AutoClosable in the try declaration, then we don't need to close the resource ourselves.
--> Multiple catch blocks:-
Sometimes, the code can throw more than one exception, and we can have more than one catch block handle each exception individually.
E.g.:-
public int getPlayerScore(String playerFile) {
try (Scanner contents = new Scanner(new File(playerFile))) {
return Integer.parseInt(contents.nextLine());
} catch (IOException e) {
logger.warn("Player file wouldn't load!", e);
return 0;
} catch (NumberFormatException e) {
logger.warn("Player file was corrupted!", e);
return 0;
}
}
Note:- We didn't catch FileNotFoundException, and that is because it extends IOException. Because we're catching IOException, Java will consider any of its subclasses also handled.
--> Union catch Blocks:-
When we know that the way we handle errors is going to be the same, Java 7 gave the ability to catch multiple exceptions in the same block.
E.g.:-
public int getPlayerScore(String playerFile) {
try (Scanner contents = new Scanner(new File(playerFile))) {
return Integer.parseInt(contents.nextLine());
} catch (IOException | NumberFormatException e) {
logger.warn("Failed to load score!", e);
return 0;
}
}
Note:- The exceptions caught in the catch block should not have "is-a" relationship.