让构造函数抛出异常是一种好的做法吗?例如,我有一个Person
类,并且age
是它唯一的属性。现在我将这个类提供为
class Person{
int age;
Person(int age) throws Exception{
if (age<0)
throw new Exception("invalid age");
this.age = age;
}
public void setAge(int age) throws Exception{
if (age<0)
throw new Exception("invalid age");
this.age = age;
}
}
发布于 2012-05-07 05:44:30
您不需要引发检查过的异常。这是程序控制范围内的一个bug,因此您希望抛出一个未检查的异常。使用Java语言已经提供的未检查异常之一,比如IllegalArgumentException
、IllegalStateException
或NullPointerException
。
您可能还想摆脱setter。您已经提供了一种通过构造函数启动age
的方法。实例化后是否需要更新?如果不是,则跳过setter。一条好的规则是,不要把事情公之于众。从私有或默认开始,使用final
保护您的数据。现在每个人都知道Person
已经被正确构造,并且是不可变的。它可以自信地使用。
这很可能是你真正需要的:
class Person {
private final int age;
Person(int age) {
if (age < 0)
throw new IllegalArgumentException("age less than zero: " + age);
this.age = age;
}
// setter removed
发布于 2011-05-22 14:47:24
这是完全正确的,我一直都在这么做。如果它是参数检查的结果,我通常使用IllegalArguemntException。
在这种情况下,我不建议使用断言,因为它们在部署构建中被关闭,您总是希望阻止这种情况发生,但如果您的团队在启用断言的情况下执行所有测试,并且您认为在运行时丢失参数问题的可能性比抛出可能更有可能导致运行时崩溃的异常更容易接受,则断言是有效的。
而且,assert对于调用者来说更难捕获,这很容易。
您可能希望在方法的javadoc中将其列为“抛出”,并说明原因,这样调用者就不会感到惊讶。
发布于 2011-05-22 14:31:39
我从来不认为在构造函数中抛出异常是一种糟糕的做法。在设计类时,您应该对该类的结构有一定的了解。如果其他人有不同的想法并试图执行该想法,那么您应该相应地出错,给用户关于错误是什么的反馈。在您的情况下,您可能会考虑如下内容
if (age < 0) throw new NegativeAgeException("The person you attempted " +
"to construct must be given a positive age.");
其中,NegativeAgeException
是您自己构造的异常类,可能会扩展另一个异常,如IndexOutOfBoundsException
或类似的异常。
断言似乎也不太合适,因为您并不是在尝试发现代码中的bug。我想说,在这里使用异常终止绝对是正确的做法。
https://stackoverflow.com/questions/6086334
复制相似问题