views:

148

answers:

10

I know that this would be bad practice although I know that I would not be able to explain why.

int [] intArr = ...
...
try{
   int i = 0;
   while(true){
      System.out.println(intArr[i++]);
   }
}catch(ArrayIndexOutOfBoundsException e){}

I think that you are only supposed to use exceptions for things that shouldn't happen. I am asking this question because I think that I am using exceptions wrong sometimes. If your programming is running a standard case should exceptions be thrown?

This seems related: http://stackoverflow.com/questions/894829/java-opinion-preventing-exceptions-vs-catching-exceptions

+12  A: 

You are right: exceptions are meant for, ehm, exceptional cases. Using them for controlling normal control flow is not only obscuring the intent of the code (which would be enough to disqualify it already), but also is much slower, since throwing and catching exceptions is costly.

The standard idiom (in Java5 and above) is using a foreach loop:

for (int i : intArr) {
  System.out.println(i);
}
Péter Török
+1 Which is why you shouldn't use Integer.Parse if you know it will fail regularly. Ex parse xxxxxx numbers where multiple could fail. Instead you would use something like int.TryParse in C# (java equivalent). Exceptions is fast when they are not thrown. But when they are thrown they are rather slow (create new object with message, go through a lot of nested catch etc.).
lasseespeholt
@Lassee While I agree with your logic, I don't believe there is a java equivalent of TryParse
glowcoder
+1  A: 

You are correct. Exceptions should not be used to handle process flow.

akf
+3  A: 

It's wrong because you know that eventually the loop will reach the last element of intArr, so there's nothing exceptional in this, you're actually expecting this behaviour.

Alberto Zaccagni
+1  A: 

Eating exceptions the way you do is usually considered a bad practice : if you don't have to do any further treatment, you can log it.

Jean-Philippe Caruana
+1  A: 

Only in exceptional situations like,

  • when a method cannot do what it is supposed to do
  • not to control the execution flow
this. __curious_geek
+1  A: 

As always "it depends" and you will find many differing opinions. Here's mine

  • Exceptions fall into two general categories.
    • Things you can reasonably anticipate and handle (FileNotFoundException)
    • Things you generally don't antipicate assuming perfect code (ArrayIndexOutOfBounds)

You would expect to generally handle the first category and not the latter. The latter is usually programming errors.

Your example falls into the latter case, a programming error. The exception is intended to give good information about the failure at runtime, not act as a control flow.

Some people will say that the first is checked exceptions and the second is unchecked. I would disagree with that. I almost always find checked exceptions a pain in reality as you almost always end up doing catch/wrap/rethrow to another exception type. When throwing exceptions and defining my own exception classes I almost always use unchecked.

Mike Q
+1  A: 

Exceptions should catch something exceptional, log it, and recover if possible.

If it's part of normal program flow, you should handle it normally.

Dean J
+1  A: 

Exceptions are for exceptions in the code. Not for standard cases.

however, there are one more serious issue with your code, it is slower the it would be without the use of exception. Creating the exception, throwing the exception and catching the exception takes additional CPU and MEMORY.

Also the code gets harder to read for other programmers that only expect Exceptions to be thrown on error cases.

UnixShadow
+2  A: 

Catching exceptions is only a bad practice when it concerns a RuntimeException. The ArrayIndexOutOfBoundsException which you're trying to catch there is one.

RuntimeExceptions identify programmatically recoverable problems which are caused by faults in code flow. You should not fix them by catching them, but by writing proper code and making use of flow control statements like if/else, while, for, etc.

See also:

BalusC
+1  A: 

Reaching the end of an array is not an exceptional case. You know the length before you start looping, so just use a standard idiom.

for(int i = 0; i < intArr.length; ++i) {
    System.out.println(intArr[i]);
} 
Bill the Lizard