Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Exceptions should be used only to denote exceptional conditions; they should not be used for ordinary control flow purposes. 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:

Code Block
bgColor#FFCCCC
public String processSingleString(String string) {
  // ...
  return string;
}
public String processStrings(String[] strings) {
  String result = "";
  

Wiki Markup
{{exception}} is used to improve program 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 can obfuscate the purpose of code, mask real bug 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.

Code Block
bgColor#FFCCCC

try {
    int i = 0;
  try {
    while (true) {      
      result =  a.doSomething();
   result.concat(processSingleString(strings[i]));
      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. 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

 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.

Compliant Solution

This compliant solution uses a standard for loop to concatenate the stringsA standard way of using for idiom can solve the problem.

Code Block
bgColor#ccccff

forpublic String (int i=0; i<a.length; i++) {
    a[i].doSomething();
}

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.

Code Block
bgColor#FFCCCC

tryprocessStrings(String[] strings) {
  String  Iterator iresult = collection.iterator()"";
   for while(true)int {
i = 0; i      Foo foo = (foo) i.next();
    }
} catch (NoSuchElementException e< strings.length; i++) {
    //result ongoing routine
}

Compliant Solution

A simple fix will be to implement a hasNext() method in the iterator class.

Code Block
bgColor#ccccff

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

Wiki Markup
\[[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|AA. Java References#JLS 05]\]

= result.concat( processSingleString( strings[i]));
  }
  return 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 detecting and handling exceptional conditions 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"

 

...

Image Added Image Added Image AddedCON02-J. Facilitate thread reuse by using Thread Pools      11. Concurrency (CON)      CON04-J. Do not call overridable methods from synchronized regions