Вопрос

In the case when is normal for a function to fail, for example by not finding a record in the database or any other situation that denotes possible absence of values, is it advisable to use exceptions to handle this case?

Example pseudo-code:

function retrieve(foo):
  results = db.query("SELECT * FROM bar WHERE foo="+foo)
  if not results:
    throw Exception("no results")
  return results[0]

function main:
  try:
    record = retrieve(42)
  except:
    print "no record with 42"
    .... will create the record and continue
  else:
    print "record found: "+record
    .... will use the existing record and continue

Another solution might be returning a null value instead of launching this exception. Which one is most likely to be an anti-pattern? In which cases is it better to use an exception and in which not?

Это было полезно?

Решение

Joshua Bloch summarizes in "Effective Java":

exceptions are, as their name implies, to be used only for exceptional conditions; they should never be used for ordinary control flow

You can find the corresponding snippet of the book ("Item 57: Use exceptions only for exceptional conditions") on Google books.

Besides the reason that exception-abuse can lead to code that's hard to understand Bloch has some reason that is valid for today's JVM implementations:

Because exceptions are designed for exceptional circumstances, there is little incentive for JVM implementors to make them as fast as explicit tests.

In case of the (Hotspot) JVM it's pretty expensive to create an exception (think of the generated stacktrace).

Другие советы

From the .Net Framework Development Guidelines:

DO NOT use exceptions for the normal flow of control, if possible.

Except for system failures and operations with potential race conditions, framework designers should design APIs so users can write code that does not throw exceptions. For example, you can provide a way to check preconditions before calling a member so users can write code that does not throw exceptions.

The member used to check preconditions of another member is often referred to as a tester, and the member that actually does the work is called a doer.

There are cases when the Tester-Doer Pattern can have an unacceptable performance overhead. In such cases, the so-called Try-Parse Pattern should be considered (see Exceptions and Performance for more information).

Using exceptions generally leads to higher overhead and abusing them might slow down your application. There is nothing exceptional about finding no records with a query so I would definitely suggest returning a null.

So no, using exceptions for normal control flow is not a good practice.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top