
exception
is used to improve program readability and reliability by detecting exceptional situation and possibly recover from it. However, it should not be used abusively to act as part of routine functionality. Irregular usage of exception will interrupt normal execution flow and degrade system performance[Effective Jave, item 39|http://books.google.com/books?id=ZZOiqZQIbRMC&pg=PA169&lpg=PA169&dq=item+39+use+exceptions&source=bl&ots=UZP26ufK15&sig=E60s65pIGPpYY7O79U96dx_oAqg&hl=en&ei=QLHzSsPFMMOZlAe3ioSiAw&sa=X&oi=book_result&ct=result&resnum=1&ved=0CAgQ6AEwAA#v=onepage&q=item%2039%20use%20exceptions&f=false]].
Noncompliant Code Example
In the following example, the program tries to use ArrayIndexOutOfBoundsException
to detect the end of array and then proceed with its ongoing logic.
try { int i = 0; while(true) a[i++].next(); } catch (ArrayIndexOutOfBoundsException e) { // end of array, ongoing routine }
This is not recommended because it didn't comply with the main purpose of using exception, which is to detect and recover [[EXC03-J. Try to gracefully recover from system errors]]. The normal logical flow of reaching the end of array is treated as an exception here, which has an inverse effect on readability and comprehension. Besides, exception-based idiom is far slower than standard code block in Java VM. It will prevents certain optimizations that JVM would otherwise perform.
Compliant Solution
for (int i=0; i<a.length; i++) { a[i].f(); }
Noncompliant Code Example
In another sense, an exposed API should not force its clients to use exceptions for ordinary control flow. A class that has state-dependent
method should also have a state-testing
method to accompany it, so as to decide whether the first method should be called. In the following example, because iterator class didn't has a hasNext()
method, the caller is forced to use exception to detect the end of iterator.
try { Iterator i = collection.iterator(); while(true) { Foo foo = (foo) i.next(); } } catch (NoSuchElementException e) { // ongoing routine }
Compliant Solution
A simple fix will be to implement a hasNext()
method in the iterator
class.
for (Iterator i = collection.iterator(); i.hasNext();) { Foo foo = (Foo) i.next(); ... }
Risk Assessment
The abusive usage of exception can result in performance degrade and poor logical flow design.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXC10- J |
low |
unlikely |
medium |
P3 |
L3 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[Effective Jave, item 39|http://books.google.com/books?id=ZZOiqZQIbRMC&pg=PA169&lpg=PA169&dq=item+39+use+exceptions&source=bl&ots=UZP26ufK15&sig=E60s65pIGPpYY7O79U96dx_oAqg&hl=en&ei=QLHzSsPFMMOZlAe3ioSiAw&sa=X&oi=book_result&ct=result&resnum=1&ved=0CAgQ6AEwAA#v=onepage&q=item%2039%20use%20exceptions&f=false]]
[[Java Reference 05]]
CON02-J. Facilitate thread reuse by using Thread Pools 11. Concurrency (CON) CON04-J. Do not call overridable methods from synchronized regions