2

So, I have a class called Puzzle, and two (relevant) constructors for it. One constructor accepts no args, and the other takes an int, but also throws an exception. The basic idea is like this:

public class Puzzle {
    // Fields, methods, etc.
    public Puzzle() {
        this(3);
    }

    public Puzzle(int n) throws Exception {
        if (n < 2) throw new Exception();

        // More constructor code
    }
}

Of course, this doesn't compile, because the constructor that takes an int throws an exception, and the constructor without args doesn't handle or throw the exception. But, since it is plain to see that the exception never will be thrown (there are no more exceptions thrown in the body of the constructor), this shouldn't matter. I could just use a blank try-catch statement like this:

public Puzzle() {
    try {
        this(3);
    } catch (Exception e) {
        // Never happens
    }
}

The problem here is that the call to this(3) is no longer the first statement of the constructor, so it won't compile. It seems like I have to mark this constructor with a throws clause even though I know it will never throw an exception. This is really annoying, because calling code will then need to have unnecessary try-catch blocks or they will have to throw the exception too. Is there an elegant way around this that I'm missing? I know I could easily copy and paste some code, but that goes against the grain of all that is holy in OOP. Any ideas?

2 Answers 2

6

Use a runtime exception. Specifically, IllegalArgumentException is designed for this.

Sign up to request clarification or add additional context in comments.

5 Comments

This was the simplest solution which required the least amount of modification. Thanks!
As it's something which should never happen, use AssertionError. Use IllegalArgumentException when there is an illegal argument.
@PeterLawrey - not understanding your argument here. i associate AssertionError with violating internal invariants which should never happen (aka you have a logic bug in your code).
@jtahlborn That's what I take // Never happens to mean. i.e. this can only happen if some serious internal error occurred. It's the error that assert false; throws.
@PeterLawrey - oh, you're talking about how to re-throw the exception. my answer was addressing the original Exception throw (at least, that was my intent).
1

Break out the code in the constructor to a private initializer method:

public class Puzzle {
    // Fields, methods, etc.
    public Puzzle() {
        construct(3);
    }

    public Puzzle(int n) throws Exception {
        if (n < 2) throw new Exception();

        construct(n);        

    }

    private void construct(int n) {
        // More constructor code
    }
}

3 Comments

a workable idea, although private initializers are a pain cause you can't use final members.
@jtahlborn true. Your answere is a better way to do this.
+1 for a workable solution, though. I can't believe I didn't come up with something like that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.