1

I've learned that Exception is slow:

How slow are Java exceptions?

but this article(http://blogs.atlassian.com/2011/05/if_you_use_exceptions_for_path_control_dont_fill_in_the_stac/) says that we can use Exception to simulate a goto statement:

so I think it's ok to write my code like this:

public class MyService {

    public Result service(int i) {
        Result result = new Result();
        try {

            Util.checkCommonArguments(i);

            //my business logic...
            if ((i % 2) != 0) {
                throw new BizException("002", "can not be odd");
            }
            if (i > 200) {
                throw new BizException("003", "can not be greater than 200");
            }

            // the normal processing...


            result.setCode("000");
            result.setDesc("ok");
        } catch (BizException e) {
            result.setCode(e.getCode());
            result.setDesc(e.getMessage());
        } catch (Exception e) {
            result.setCode("999");
            result.setDesc("system error");
        }
        return result;
    }


}

class Util {
    public static void checkCommonArguments(int input) {
        if (input < 0) {
            throw new BizException("001", "can not be negative.");
        }
        //maybe more
    }
}

class Result {

    private String code;
    private String desc;

    //getter and setter
}

class BizException extends RuntimeException {
    private String code;

    public BizException(String code, String message) {
        super(message);
        this.code = code;
    }
    @Override
    public Throwable fillInStackTrace()
    {
        return this;
    }
}

but 'dont fill in the stack trace' does not work:

// throw but catch, but not Filling in exception stack traces 
public void method5(int i) {
    try {
        value = ((value + i) / i) << 1;
        // i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
        // an AND operation between two integers. The size of the number plays
        // no role. AND on 32 BIT always ANDs all 32 bits
        if ((i & 0x1) == 1) {
            throw new MyBizException();
        }
    } catch (MyBizException e) {
        //maybe do something
    }
}

method5's cost time is almost the same as:

    // This one will regularly throw one
public void method3(int i) throws Exception {
    value = ((value + i) / i) << 1;
    // i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
    // an AND operation between two integers. The size of the number plays
    // no role. AND on 32 BIT always ANDs all 32 bits
    if ((i & 0x1) == 1) {
        throw new Exception();
    }
}

Now I'm confused. On one side, I want my code clean and clear(like the class 'MyService'). On the other side, Exception is really slow.

Should I use Exception to simulate a goto statement? Thanks.

Community
  • 1
  • 1
bylijinnan
  • 756
  • 3
  • 11
  • 27
  • Please add your actual question in the question body. – Sotirios Delimanolis Mar 31 '15 at 00:59
  • It's not a bad approach, actually quite common. Two things to comment on: *You don't simulate gotos*, those BASIC days are over. But of course you change the flow of execution. *You can only handle one exception at a time* - which might or might not be appropriate for your validation. Another common pattern would be to add to some sort of validation error list... – Jan Groth Mar 31 '15 at 01:00

2 Answers2

4

Don't use exceptions for normal program flow. They are for exceptional circumstances beyond the developer's control. They are slow, inefficient, and designed for error handling, not business logic.

Stimulating a goto is a bad design decision in today's development environment anyways. They are confusing to follow, and difficult to maintain. Refactor your code to use breaks or other control logic instead.

Tim
  • 2,878
  • 1
  • 14
  • 19
  • Not sold on the "*exceptional circumstances*" part. You don't manually validate a `String` before you convert it to an `Integer` just to avoid a "*slow and inefficient*" `NumberFormatException`, do you? ;) – Jan Groth Mar 31 '15 at 01:28
  • @jangroth No, but that's because there is no alternative. It would have been better if `Integer.valueOf(string)` returned `null` rather than throwing a `NumberFormatException`. – Paul Boddington Mar 31 '15 at 02:19
  • In many languages I would actually. In .Net I would tryparse, in others I would check it natively there. As mentioned when you don't have a good choice, you go with it. But regardless, if I expect a string to be numeric when passed to me, then the fact it isn't is actually exceptional. Expected number, got something else. If I was writing a contact for that call I would put in there that I expected a string representation of a number. – Tim Mar 31 '15 at 03:21
0

Using exception for flow control is neither in the interest of good design nor efficient. At the very minimum this will create unnecessary objects. I would encourage you to have a look at Joshua Bloch's "Effective Java" which explicitly covers this topic.

Y123
  • 915
  • 13
  • 30