我最近在考虑从Java投掷构造函数是否好。目前这是我收集的内容:
Can constructors throw exceptions in Java?
在这里,StackOverflow先生(又名Jon Skeet)似乎没有任何反对意见,但他确实暗示要让子类抛出异常。当子类抛出异常时会发生什么(有什么不好?)
http://futuretask.blogspot.com/2006/05/java-tip-10-constructor-exceptions-are.html
这篇博客文章“构造函数异常是邪恶的”告诉我一种方法来表明构造函数异常可能是危险的。然而,这个例子似乎真的很深奥。这里有真正的危险吗?
我在想如果使用静态工厂方法(Effective Java 2nd ed。,Item 1)而不是公共构造函数,我们可以安全地从构造函数中删除异常到静态工厂方法。这是避免构造函数异常的有效方法吗?这在任何地方都有用或使用吗?
任何输入都有帮助&赞赏。谢谢!
答案 0 :(得分: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();
}
}
}
现在,Child
类
close()
被另一层继承覆盖,那么也会导致问题。另一个例子,说明继承如何变得混乱。
我仍然认为构造函数抛出异常基本上没什么问题。甚至你的第二个链接更多的是关于捕获未成功构造的对象的邪恶方式,而不是真正关于构造函数异常是邪恶的 - 它肯定不会给出任何原因不抛出构造函数的异常。它甚至没有给我提到的混乱情况。
工厂方法可以可能有帮助,但就调用者而言,结果是相同的:他们不会看到部分构造的对象。除非你真的需要做一些事情,比如清理一个被构造的对象,但后来验证了一些元素,我不认为这应该是使用工厂方法而不是构造函数的理由。 (其他理由这样做,但这是另一回事。)
答案 1 :(得分:8)
构造函数(或工厂方法)中的异常没有任何问题,无论哪种方式都可以。有时,在构造函数中做太多工作可能是一个糟糕的设计,并且可能有意义转移到工厂方法。
第2点证明的唯一问题是构造函数中的异常不是保护类不受邪恶使用的适当安全机制。但是,有许多方法可以破坏这样的设计,这就是为什么真正在java中运行安全代码的唯一方法是使用SecurityManager运行。所以第2点只是一个稻草人的论点。
答案 2 :(得分:1)
我相信从构造函数中抛出异常很好,更多的是检查成功创建对象的前提条件,例如IllegalArgumentException。 但是,我不相信构造函数是处理业务逻辑或抛出业务异常/自定义异常的正确位置。
至于引用不引起例外的原因,恕我直言,他们是非常做作的;最重要的是,如果一个不小心的开发者希望做一些邪恶的事情,他可以找到很多方法去做,并且在开发人员对代码进行自我审查/遵循最佳实践之前不会停止。