0

I was wondering when it makes sense to throw checked exceptions in constructors. Until now I´ve always used RuntimeExceptions when validating constructor/method arguments. Short Pro/Cons I came up with:

Pro:

  • Error recovery possible (catch)

Contra:

  • Creating new instances requires a try-catch block -> ugly

For example:

/**
 * Represents a savings-account.
 * A savings-account must always have a positive balance.
 */
public class SavingsAccount extends Account {
    /**
     * Creates a new savings-account.
     *
     * @param id      unique account identifier
     * @param balance Initial account balance (in cents).
     *                Must be greater than zero (>0).
     */
    public SavingsAccount(int id, int balance) throws AccountException {
        super(id, balance);

        if (getBalance() <= 0) {
            // TODO: Throw exception.
        }
    }
    // methods ...

I know that this is a very primitive example but it´s just for demonstration purposes. My intuition tells me that throwing a checked exception here makes sense, because the caller of the constructor may recover if the account is in an invalid state.

OR should I assume that the caller of the constructor knows its preconditions (from the documentation) and will always pass valid values? And if not, just throw a RuntimeException.

Any tips on what´s best for such scenarios?

Elias
  • 563
  • 4
  • 18
  • https://stackoverflow.com/questions/6086334/is-it-good-practice-to-make-the-constructor-throw-an-exception – Thiyagu Mar 17 '18 at 17:00

1 Answers1

0

Checked exceptions are a design flaw in Java. Most of the times, the caller does nothing to recover from the exception, but is still forced to handle it. None of the JVM languages that came later (Scala, Groovy, Kotlin) have checked exceptions. The Java designers realize this as well, and have been providing subtle means to get around the nonsense called checked exceptions, example UncheckedIOException.

Nothing stops the caller from catching a RuntimeException and dealing with it for, say, retrying. You don’t have to be in their face for them to be able to do that. You could put it in Javadoc, many methods in JDK do, like when you attempt to get an element from an empty list. enter image description here

Making a constructor throw a CheckedException means you’re responsible for clean up until the point the exception is thrown.

Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219
  • 1
    *Checked exceptions are a design flaw in Java.* - This is highly opinionated. – lexicore Mar 17 '18 at 17:10
  • 1
    The reason for the existence of `UncheckedIOException` is not that the Java designers realized checked exceptions as a design flaw. It is there to have a possibility of using IO operations in lambda expressions that fulfill the role of a `Function`, a `Consumer`, or a `Supplier` (and of course, others). These interfaces have a method without an exception! – Seelenvirtuose Mar 17 '18 at 17:12
  • @lexicore thanks for the obvious. The rest of the answer is there to support that opinion. Now other than your opinion that my answer is opinionated, if you’ve technical details to support it, bring it on the table. – Abhijit Sarkar Mar 17 '18 at 17:13
  • @Seelenvirtuose other than `new RuntimeException(“$hit happens”, ioException`), I suppose you can point me to documentation that supports what you said – Abhijit Sarkar Mar 17 '18 at 17:16
  • 2
    @AbhijitSarkar Well, of course my opinion is opinionated as well. :) This is why I don't post it as an answer. I have worked with a very large codebase where previous devs only used unchecked exceptions exactly for the reasons you mention. It was a disaster and it took us a lot of effort to stabilize. One of the primary measures was introducing a reasonable checked/unchecked exception policy. It got much better with checked exceptions. This is, of course, anecdotal, but it is enough for me to never agree with *Checked exceptions are a design flaw in Java* answer. Hence the downvote. – lexicore Mar 17 '18 at 17:26
  • Ok, I see that this topic is so to say a double-edged sword. Anyway, I like the idea that a RuntimeException doesn´t force you to catch the exception but instead gives you the option to do so. That way I can later on decide if I want to recover or not or if the calling code has to make sure the paramters are valid. – Elias Mar 17 '18 at 17:33
  • @lexicore thanks for elaborating, but “using checked exceptions stabilized our code” is a dubious and questionable claim because you’ve not provided us any way to verify that statement. It’s like saying marriage is inherently flawed because you had a divorce without considering that you might have been the reason for the split. In other words, it’s entirely possible to write crap code regardless of the exception type in your code. – Abhijit Sarkar Mar 17 '18 at 18:00
  • @AbhijitSarkar This is my personal experience. Feel free to call it dubious and questionable, I'm fine with it. I have only provided a reason for my downvote. – lexicore Mar 17 '18 at 18:24