2

Problem

I have a class with two constructors. One of them (A) throws a checked exception, and the other one (B) calls the first one.

// Constructor A
public ArrayValue(DataType rules, Value... content) throws NonExpressionException {
    super(rules.type);
    ...
}

// Constructor B
public ArrayValue(Value... content) {
    this(TypeConstants.VAR_ARR, content);
}

The problem is, that this checked exception will never get thrown when constructor B is invoked, so I thought of "catching" it instead of adding a "throws" to this constructor.

Question

What can I do to get rid of the "throws"? My conditions are:

  • The first constructor has to throw this exception.
  • It has to be checked.
  • I dont want to copy the whole code from constructor A into B.
  • I'm looking for a more elegant solution than just changing the constructor B to a static method.

I have tried

// Constructor B
public ArrayValue(Value... content) {
    try {
        this(TypeConstants.VAR_ARR, content));
    catch (NonExpressionException e) {
        throw new AssertionError("This shouldn't get thrown", e);
    }
}

(But that doesn't work, because this() has to be the first statement in a constructor.)

5
  • I would suggest rather throw in method, where these input variables are being used. Commented May 31, 2022 at 12:18
  • A third private constructor without throw being used by the current two ones. Commented May 31, 2022 at 12:20
  • @GauravJeswani The exception cannot be handled in that methods and has to be "transported" over the constructor. Commented May 31, 2022 at 12:21
  • @JoopEggen I'm afraid thats not possible. Constructor A calls some methods that throw this exception and are not able to handle it themselves. In fact, nothing in this class can handle these Exceptions, they have to get out of there, I just want to minimise that, whereever I can. Commented May 31, 2022 at 12:26
  • 1
    Static factory method, but that is cumbersome too. It seems you have to change the usage then. Good luck. Commented May 31, 2022 at 12:48

1 Answer 1

0

For this level of flexibility, a helper factory method would come in handy:

public ArrayValue(DataType rules, Value... content) throws NonExpressionException {
    newInstance(rules, content);
}

public ArrayValue(Value... content) {
    try {
        newInstance(TypeConstants.VAR_ARR, content);
    }
    catch(NonExpressionException e) {
        assert false; // Or other error-reporting behavior
    }
}
    
private static ArrayValue newInstance(DataType rules, Value... content)
    throws NonExpressionException {
        /* ... */
    }
}

However, at this point, it might be worth considering using static factory methods instead (as suggested in the comments). In Effective Java, 3rd Edition, the first item is "Consider static factory methods instead of constructors". Bloch lists four advantages of using static factory methods instead of constructors. Interestingly, dealing with pesky checked exceptions is not one of them, but it could be.

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

Comments

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.