Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Exceptions as control flow?

I've heard that using exceptions for control flow is bad practice. What do you think of this?

public static findStringMatch(g0, g1) {

    int g0Left = -1;
    int g0Right = -1;
    int g1Left = -1;
    int g1Right = -1;

//if a match is found, set the above ints to the proper indices
//...
//if not, the ints remain -1

        try {
            String gL0 = g0.substring(0, g0Left);
            String gL1 = g1.substring(0, g1Left);

            String g0match = g0.substring(g0Left, g0Right);
            String g1match = g1.substring(g1Left, g1Right);

            String gR0 = g0.substring(g0Right);
            String gR1 = g1.substring(g1Right);

            return new StringMatch(gL0, gR0, g0match, g1match, gL1, gR1);
        }
        catch (StringIndexOutOfBoundsException e) {
            return new StringMatch(); //no match found
        }

So, if no match has been found, the ints will be -1. This will cause an exception when I try to take the substring g0.substring(0, -1). Then the function just returns an object indicating that no match is found.

Is this bad practice? I could just check each index manually to see if they're all -1, but that feels like more work.

UPDATE

I have removed the try-catch block and replaced it with this:

    if (g0Left == -1 || g0Right == -1 || g1Left == -1 || g1Right == -1) {
        return new StringMatch();
    }

Which is better: checking if each variable is -1, or using a boolean foundMatch to keep track and just check that at the end?

like image 686
Nick Heiner Avatar asked Oct 09 '09 23:10

Nick Heiner


2 Answers

Generally exceptions are expensive operations and as the name would suggest, exceptional conditions. So using them in the context of controlling the flow of your application is indeed considered bad practice.

Specifically in the example you provided, you would need to do some basic validation of the inputs you are providing to the StringMatch constructor. If it were a method that returns an error code in case some basic parameter validation fails you could avoid checking beforehand, but this is not the case.

like image 120
Yannick Motton Avatar answered Oct 06 '22 07:10

Yannick Motton


I've done some testing on this. On modern JVMs, it actually doesn't impact runtime performance much (if at all). If you run with debugging turned on, then it does slow things down considerably.

See the following for details

(I should also mention that I still think this is a bad practice, even if it doesn't impact performance. More than anything, it reflects a possibly poor algorithm design that is going to be difficult to test)

like image 22
Kevin Day Avatar answered Oct 06 '22 07:10

Kevin Day