java7新特性之Improved exception handling

java7新特性之Improved exception handling


There are two parts to this improvement—multicatch and final rethrow. To see why
they’re a help, consider the following Java 6 code, which tries to find, open, and parse
a config file and handle a number of different possible exceptions.

Listing 1.1 Handling several different exceptions in Java 6
Listing 1.1 Handling several different exceptions in Java 6
Listing 1.1 Handling several different exceptions in Java 6
public Configuration getConfig(String fileName) {
Configuration cfg = null;
try {
String fileText = getFile(fileName);
cfg = verifyConfig(parseConfig(fileText));
} catch (FileNotFoundException fnfx) {
System.err.println("Config file '" + fileName + "' is missing");
} catch (IOException e) {
System.err.println("Error while processing file '" + fileName + "'");
} catch (ConfigurationException e) {
System.err.println("Config file '" + fileName + "' is not consistent");
} catch (ParseException e) {
System.err.println("Config file '" + fileName + "' is malformed");
}
return cfg;
}


This method can encounter a number of different exceptional conditions:
■ The config file may not exist.
■ The config file may disappear while you’re trying to read from it.
■ The config file may be malformed syntactically.
■ The config file may have invalid information in it.
These conditions fit into two distinct functional groups. Either the file is missing or
bad in some way, or the file is present and correct but couldn’t be retrieved properly
(perhaps because of a hardware failure or network outage).
It would be nice to compress this down to just these two cases, and handle all the
“file is missing or bad in some way” exceptions in one catch clause. Java 7 allows you
to do this.

public Configuration getConfig(String fileName) {
Configuration cfg = null;
try {
String fileText = getFile(fileName);
cfg = verifyConfig(parseConfig(fileText));
} catch (FileNotFoundException|ParseException|ConfigurationException e) {
System.err.println("Config file '" + fileName +
"' is missing or malformed");
} catch (IOException iox) {
System.err.println("Error while processing file '" + fileName + "'");
}
return cfg;
}


The exception ehas a type that isn’t precisely knowable at compile time. This means
that it has to be handled in thecatch block as the common supertype of the exceptions that itcould be (which will often beException orThrowable, in practice).
An additional bit of new syntax helps with rethrowing exceptions. In many cases,
developers may want to manipulate a thrown exception before rethrowing it. The
problem is that in previous versions of Java you’ll often see code like this:


try {
doSomethingWhichMightThrowIOException();
doSomethingElseWhichMightThrowSQLException();
} catch (Exception e) {
...
throw e;
}

This forces you to declare the exception signature of this code as Exception—the real
dynamic type of the exception has been swallowed.

Nevertheless, it’s relatively easy to see that the exception can only be an IOException
or a SQLException, and if you can see it, so can the compiler. This snippet changes a
single word change to use the Java 7 syntax:

try {
doSomethingWhichMightThrowIOException();
doSomethingElseWhichMightThrowSQLException();
} catch (final Exception e) {
...
throw e;
}

The appearance of the final keyword indicates that the type that’s actually thrown is
the runtime type of the exception that was encountered—in this example, that would
be either IOException or SQLException. This is referred to as final rethrow, and it can
protect against throwing an overly general type, which then has to be caught by a very
general catch in a higher scope.
The final keyword is optional in the previous example, but in practice, we’ve
found that it helps to use it while adjusting to the new semantics of catch and rethrow.


读书笔记:The Well-Grounded Java Develope

你可能感兴趣的:(exception,h,Improved,java7新特性之)