Exceptions should only be used only to denote exceptional conditions. They ; they should not be used for ordinary control flow purposes.
Noncompliant Code Example
Catching a generic object such as Throwable is likely to catch unexpected errors; see ERR08-J. Do not catch NullPointerException or any of its ancestors for examples. When a program catches a specific type of exception, it does not always know from where that exception was thrown. Using a catch clause to handle an exception that occurs in a distant known location is a poor solution; it is preferable to handle the error as soon as it occurs—or to prevent it if possible.
The nonlocality of throw statements and corresponding catch statements can also impede optimizers from improving code that relies on exception handling. Relying on catching exceptions for control flow also complicates debugging because exceptions indicate a jump in control flow from the throw statement to the catch clause. Finally, exceptions need not be highly optimized, as it is assumed that they are thrown only in exceptional circumstances. Throwing and catching an exception frequently has worse performance than handling the error with some other mechanism.
Noncompliant Code Example
This noncompliant code example attempts to concatenate the processed elements of the strings array:This noncompliant code example attempts to concatenate a few string elements of array c and store the result as the first element. It uses an ArrayIndexOutOfBoundsException to detect the end of the array and initialize the value of variable i to 0 in the catch block. However, if some element of the array is null, a NullPointerException results. This exception is caught and ignored, a violation of EXC09-J. Do not catch NullPointerException. Consequently, the variable i is not initialized to 0 as expected.
| Code Block | ||
|---|---|---|
| ||
String c[] = new String[3]; c[0] = "value1"; c[1] = "value2"; c[2] = "value3"; int i; c[1] = null; // gets null value public String processSingleString(String string) { // ... return string; } public String processStrings(String[] strings) { String result = ""; int i = 0; try { i = 0; while while(true) { c[0]result = c[0]result.concat(processSingleString(cstrings[i + 1])); // Concatenate and store in c[0] i++; } } catch (ArrayIndexOutOfBoundsException e) { i = 0; // Attempts to initialize i to 0 } catch (NullPointerException npe) { // Ignores } Ignore, we're done } return result; } |
This code uses an ArrayIndexOutOfBoundsException to detect the end of the array. Unfortunately, since ArrayIndexOutOfBoundsException is a RuntimeException, it could be thrown by processSingleString() without being declared in a throws clause. So it is possible for processStrings() to terminate prematurely before processing all of the strings.The real purpose of exception handling is to detect and recover from exceptional conditions and not to willfully transfer control flow. Besides, performance wise, the exception-based idiom is far slower than the standard code block. It also prevents certain optimizations that JVM would otherwise perform.
Compliant Solution
This compliant solution uses a standard for loop to concatenate the strings.
| Code Block | ||
|---|---|---|
| ||
public String cprocessStrings(String[] =strings) { new String[3]; c[0] = "value1"; c[1] result = "value2"; c[2] = "value3"; int i; for (int i = 10; i < cstrings.length; i++) { c[0] result = c[0]result.concat( processSingleString(c strings[i])); } i =return 0; // Initialize i to 0 after operation |
Risk Assessment
result;
} |
This code need not catch ArrayIndexOutOfBoundsException because it is a runtime exception, and such exceptions indicate programmer errors, which are best resolved by fixing the defect.
Applicability
Use of exceptions for any purpose other than The use of exceptions for anything but detecting and handling exceptional conditions can result in performance degradation and poor design.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
EXC10- J | low | unlikely | medium | P2 | L3 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
| Wiki Markup |
|---|
\[[Bloch 01|AA. Java References#Bloch 01]\] Item 39: "Use exceptions only for exceptional conditions"
\[[JLS 05|AA. Java References#JLS 05]\] |
complicates program analysis and debugging, degrades performance, and can increase maintenance costs.
Bibliography
| [Bloch 2001] | Item 39, "Use Exceptions Only for Exceptional Conditions" |
| [JLS 2013] | Chapter 11, "Exceptions" |
...
CON02-J. Facilitate thread reuse by using Thread Pools 11. Concurrency (CON) CON04-J. Do not call overridable methods from synchronized regions