Now the processing time of the toString() method dominates the calculation. There is still
a penalty to pay for creating the exceptions with deep stacks, but the benefit from testing for
the null value in advance has all but vanished.
So performance penalties for using exceptions injudiciously is smaller than might be expec-
ted. Still, there are cases where you will run into code that is simply creating too many ex-
ceptions. Since the performance penalty comes from filling in the stack traces, the -XX:-
StackTraceInThrowable flag (which is true by default) can be set to disable the generation
of the stack traces.
This is rarely a good idea: the stack traces are present to enable some analysis of what unex-
pectedly went wrong. That capability is lost when this flag is enabled. And there is code that
actually examines the stack traces and determines how to recover from the exception based
on what it finds there. (The reference implementation of CORBA works like that.) That's
problematic in itself, but the upshot is that disabling the stack trace can mysteriously break
There are some APIs in the JDK itself where exception handling can lead to performance is-
sues. Many collection classes will throw an exception when nonexistent items are retrieved
from them. The Stack class, for example, throws an EmptyStackException if the stack is
empty when the pop() method is called. It is usually better to utilize defensive programming
in that case by checking the stack length first. (On the other hand, unlike many collection
classes, the Stack class supports null objects, so it's not as if the pop() method could return
null to indicate an empty stack.)
The most notorious example within the JDK of questionable use of exceptions is in class-
loading: the loadClass() method of the ClassLoader class throws a ClassNotFoundEx-
ception when asked to load a class that it cannot find. That's not actually an exceptional
condition. An individual classloader is not expected to know how to load every class in an
application, which is why there are hierarchies of classloaders.
In an environment with dozens of classloaders, this means a lot of exceptions are created as
the classloader hierarchy is searched for the one classloader that knows how to load the given
class. The classloading example earlier in this chapter, for example, runs 3% faster when
stack trace generation is disabled.
Still, that kind of difference is the exception more than the rule. That classloading example is
a microbenchmark with a very long classpath, and even under those circumstances, the dif-
ference per call is on the order of a millisecond.