|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
First, let's distinguish how Java checks the exceptions a method declares it throws from how it checks the exceptions that
a catch clause catches. (In this article, when I say exception with a lowercase e, I mean java.lang.Throwable and its subclasses. When I mean a specific class, like java.lang.Exception, I include the package or at least capitalize the class name.) Initially, the approaches seem quite similar: both indicate
the exceptions expected to be thrown by the code block with which they're associated. But while Java requires a method to
declare the exceptions that it throws, it doesn't require a method to throw every exception it declares for a good reason:
Java allows you to design APIs that remain stable as you add functionality.
Consider this initial version of a home-brewed connection pool:
public class ConnectionPool {
public ConnectionPool() throws ConnectionException {
}
public Connection getConnection() throws ConnectionException {
// Allocate a connection (possibly throwing a ConnectionException or a
// subclass) if necessary, then return it
}
}
While the code in getConnection() might throw a ConnectionException, the constructor does nothing, so in this implementation, the method doesn't really need to declare any exceptions. But in
the next version, we might rewrite the class to speed up getConnection():
public class ConnectionPool {
public ConnectionPool() throws ConnectionException {
// Allocate all the connections we think we'll ever need
}
public Connection getConnection() throws ConnectionException {
// Allocate a connection if necessary (not likely), then return it
}
}
Because we made the constructor in the first version declare ConnectionException, code that uses it doesn't have to change to use the second version. Java trades some checking it could do in the throws
clause for the sake of long-term stability in all the other classes that call the constructor—not a bad bargain at all.
Catch clauses are a different story from throws clauses. The API stability argument doesn't apply: while a method declaration is part of a class's public interface, a try/catch block is an implementation detail hidden from callers. Not only is there no reason for a catch clause to catch an exception that its try block doesn't throw, guaranteeing that it doesn't do so can catch serious coding errors. For these reasons, Java requires your try blocks to actually throw the exceptions that their catch clauses catch. For example, if you were homesick for your old operating system and wrote the following little utility,