开发者

Java: Exception in constructors: Problematic or not?

开发者 https://www.devze.com 2023-04-06 20:17 出处:网络
I am recently thinking about if throwing constructor from Java is good or not. Currently this is what I gathered:

I am recently thinking about if throwing constructor from Java is good or not. Currently this is what I gathered:

  1. Can constructors throw exceptions in Java?

    Here, Mr. StackOverflow (aka Jon Skeet) does not seem to hold anything against it, but he did hint about having subclass throwing exceptions. What will happen (anything bad?) when subclass throws exceptions?

  2. http://futuretask.blogspot.com/2006/05/java-tip-10-constructor-exceptions-are.html

    This blog post "Constructor Exceptions are Evil" tells me a way to show that constructor exceptions could be dangerous. However, the example seem to be really esoteric. Is there any real danger here?

  3. I am thinking that if static factory methods (Effective Java 2nd ed., Item 1) are used instead of public constructors, we could safely remove the exceptions from const开发者_运维知识库ructors to the static factory method. Is this a valid way to avoid constructor exceptions and is this useful or used in anywhere?

Any inputs are helpful & appreciated. Thanks!


There is nothing wrong with exceptions in constructors (or factory methods, either way is fine). sometimes, doing too much work in a constructor can be a poor design, and may make sense to move to a factory method.

the only thing that point 2 proves is that exceptions in constructors are not an adequate security mechanism for protecting a class from evil usage. however, there are any number of ways to subvert such a design, which is why the only way to truly run secure code in java is running with a SecurityManager. so point 2 is just a straw man argument.


My point about a subclass throwing an exception is a situation like this:

public class Parent {
    private final InputStream stream;

    public Parent() {
        stream = new FileInputStream(...);
    }

    public void close() throws IOException {
        stream.close();
    }
}

public class Child extends Parent {
    public Child() {
        // Implicit call to super()
        if (someCondition) {
            throw new RuntimeException();
        }
    }
}

Now the Child class really should call close() if it's going to throw an exception. Of course, if close() is overridden by yet another layer of inheritance, that could also cause problems. Just another example of how inheritance gets messy.

I still think it's basically fine for constructors to throw exceptions. Even your second link was more about an evil way of capturing the not-successfully-constructed object rather than really about constructor exceptions being evil - it certainly doesn't give any reasons for not throwing exceptions from constructors. It doesn't even give the messy situation I mentioned.

Factory methods could potentially help, but as far as the caller is concerned the result is the same: they don't get to see the partially-constructed object. Unless you really need to do something like clean-up on an object which was constructed but then failed some element of validation, I don't think that should be a reason to use factory methods instead of constructors. (There are other reasons to do so, but that's a different matter.)


I believe throwing exceptions from constructors is fine, more so the one's which checks for the preconditions to a successful object creation, example IllegalArgumentException. However, I do not believe that constructors are the right place to handle business logic or throw business exception/ custom exceptions.

As for the reasons cited to not throw an exception, IMHO they are quite contrived; bottom line is if a careless developer wishes to do something evil he can find numerous ways to do it and there's no stopping till the developer does a self review of the code/ follows best practices.

0

精彩评论

暂无评论...
验证码 换一张
取 消