Using Exceptions Without the Stack Trace Overhead Conditional Error Checking

- 138 - definitely return false. Given this, it is actually quite interesting that with a JIT, there is no difference in times between the two instanceof tests. Because it is impossible to add methods to classes that are compiled as opposed to classes you have the source for and can recompile, there are necessarily places in Java code where you have to test for the type of object. Where this type of code is unavoidable, you should use instanceof , as shown in test2 , rather than a speculative class cast. There is no maintenance disadvantage in using instanceof , nor is the code any clearer or easier to alter by avoiding its use. I strongly advise you to avoid the use of the speculative class cast, however. It is a real performance hog and ugly as well.

6.1.3 Using Exceptions Without the Stack Trace Overhead

You may decide that you definitely require an exception to be thrown, despite the disadvantages. If the exception is thrown explicitly i.e., using a throw statement rather than a VM-generated exception such as the ClassCastException or ArrayIndexOutOfBoundsException , you can reduce the cost by reusing an exception object rather than creating a new one. Most of the cost of throwing an exception is incurred in actually creating the new exception, which is when the stack trace is filled in. Reusing an existing exception object without resetting the stack trace avoids the exception-creation overhead. Throwing and catching an existing exception object is two orders of magnitude faster than doing the same with a newly created exception object: public static Exception REUSABLE_EXCEPTION = new Exception ; ... Much faster reusing an existing exception try {throw REUSABLE_EXCEPTION;} catch Exception e {...} This next try-catch is 50 to 100 times slower than the last try {throw new Exception ;} catch Exception e {...} The sole disadvantage of reusing an exception instance is that the instance does not have the correct stack trace, i.e., the stack trace held by the exception object is the one generated when the exception object was created. [2] However, this disadvantage can be important for some situations when the trace is important, so be careful. This technique can easily lead to maintenance problems. [2] To get the exception object to hold the stack trace that is current when it is thrown, rather than created, you must use the fillInStackTrace method. Of course, this is what causes the large overhead that you are trying to avoid.

6.1.4 Conditional Error Checking

During development, you typically write a lot of code that checks the arguments passed into various methods for validity. This kind of checking is invaluable during development and testing, but it can lead to a lot of overhead in the finished application. Therefore, you need a technique for implementing error checks that can optionally be removed during compilation. The most common way to do this is to use an if block: public class GLOBAL_CONSTANTS { public static final boolean ERROR_CHECKING_ON = true; ... } and code in methods of other classes includes an if block like if GLOBAL_CONSTANTS.ERROR_CHECKING_ON - 139 - { error check code of some sort ... This technique allows you to turn off error checking by recompiling the application with the ERROR_CHECKING_ON variable set to false . Doing this recompilation actually eliminates all if blocks completely, due to a feature of the compiler see Section 3.5.1.4 . Setting the value to false without recompilation also works, but avoids only the block, not the block entry test. In this case, the if statement is still executed, but the block is not entered. This still causes some performance impact: an extra test for almost every method call is significant, so it is better to recompile. [3] [3] However, this technique cannot eliminate all types of code blocks. For example, you cannot use this technique to eliminate try-catch blocks from the code they surround. You can achieve that level of control only by using a preprocessor . My thanks to Ethan Henry for pointing this out.

6.2 Casts