Java:构造函数中的异常:有问题还是没有问题?

zw3*_*324 9 java constructor exception

我最近在考虑从Java抛出构造函数是否好.目前这是我收集的内容:

  1. 构造函数可以在Java中抛出异常吗?

    在这里,StackOverflow先生(又名Jon Skeet)似乎没有任何反对意见,但他确实暗示要让子类抛出异常.当子类抛出异常时会发生什么(什么都不好?)

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

    这篇博客文章"构造函数异常是邪恶的"告诉我一种方法来表明构造函数异常可能是危险的.然而,这个例子似乎真的很深奥.这里有真正的危险吗?

  3. 我想如果使用静态工厂方法(Effective Java 2nd ed.,Item 1)而不是公共构造函数,我们可以安全地从构造函数中删除异常到静态工厂方法.这是避免构造函数异常的有效方法吗?这在任何地方都有用或有用吗?

任何输入都有帮助和赞赏.谢谢!

Jon*_*eet 8

我关于抛出异常的子类的观点是这样的情况:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在Child该类真的应该调用close()它是否会抛出异常.当然,如果close()是通过继承的又一层,这可能会重写引起问题.另一个继承如何变得混乱的例子.

我仍然认为构造函数抛出异常基本上没什么问题.甚至你的第二个链接更多的是关于捕获未成功构造的对象的邪恶方式,而不是真正关于构造函数异常是邪恶的 - 它当然没有给出任何不抛出构造函数异常的理由.它甚至没有给我提到的混乱局面.

工厂方法可能有所帮助,但就调用者而言,结果是相同的:他们无法看到部分构造的对象.除非你真的需要做一些事情,比如清理一个被构造但后来失败了一些验证元素的对象,我认为这不应该是使用工厂方法而不是构造函数的理由.(还有其他原因,但这是另一回事.)


jta*_*orn 8

构造函数中的异常没有任何问题(或工厂方法,两种方式都可以).有时,在构造函数中做太多工作可能是一个糟糕的设计,并且可能有意义转移到工厂方法.

第2点证明的唯一问题是构造函数中的异常不是保护类不受邪恶使用的适当安全机制.但是,有许多方法可以破坏这样的设计,这就是为什么在java中真正运行安全代码的唯一方法是使用SecurityManager运行.所以第2点只是一个稻草人的论点.