The synchronized modifier is an implementation detail (because methods can
make themselves threadsafe in other ways) and is not formally part of the method
specification or API. Good documentation specifies explicitly whether a method is
threadsafe; you should not rely on the presence or absence of the synchronized
keyword when working with multithreaded programs.
Annotations are an interesting special case (see Chapter 4 for
more on annotations)—they can be thought of as a halfway
house between a method modifier and additional supplemen‐
tary type information.
Checked and Unchecked Exceptions
The Java exception-handling scheme distinguishes between two types of exceptions,
known as checked and unchecked exceptions.
The distinction between checked and unchecked exceptions has to do with the cir‐
cumstances under which the exceptions could be thrown. Checked exceptions arise
in specific, well-defined circumstances, and very often are conditions from which
the application may be able to partially or fully recover.
For example, consider some code that might find its configuration file in one of sev‐
eral possible directories. If we attempt to open the file from a directory it isn't
present in, then a FileNotFoundException will be thrown. In our example, we want
to catch this exception and move on to try the next possible location for the file. In
other words, although the file not being present is an exceptional condition, it is one
from which we can recover, and it is an understood and anticipated failure.
On the other hand, in the Java environment there are a set of failures that cannot
easily be predicted or anticipated, due to such things as runtime conditions or abuse
of library code. There is no good way to predict an OutOfMemoryError , for example,
and any method that uses objects or arrays can throw a NullPointerException if it
is passed an invalid null argument.
These are the unchecked exceptions—and practically any method can throw an
unchecked exception at essentially any time. They are the Java environment's ver‐
sion of Murphy's law: “Anything that can go wrong, will go wrong.” Recovery from
an unchecked exception is usually very difficult, if not impossible—simply due to
their sheer unpredictability.
To figure out whether an exception is checked or unchecked, remember that excep‐
tions are Throwable objects and that exceptions fall into two main categories, speci‐
fied by the Error and Exception subclasses. Any exception object that is an Error is
unchecked. There is also a subclass of Exception called RuntimeException —and
any subclass of RuntimeException is also an unchecked exception. All other excep‐
tions are checked exceptions.