首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >让构造函数抛出异常是一种好的做法吗?

让构造函数抛出异常是一种好的做法吗?
EN

Stack Overflow用户
提问于 2011-05-22 14:00:58
回答 4查看 175.8K关注 0票数 194

让构造函数抛出异常是一种好的做法吗?例如,我有一个Person类,并且age是它唯一的属性。现在我将这个类提供为

代码语言:javascript
复制
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;
  }
}
EN

回答 4

Stack Overflow用户

发布于 2012-05-07 05:44:30

您不需要引发检查过的异常。这是程序控制范围内的一个bug,因此您希望抛出一个未检查的异常。使用Java语言已经提供的未检查异常之一,比如IllegalArgumentExceptionIllegalStateExceptionNullPointerException

您可能还想摆脱setter。您已经提供了一种通过构造函数启动age的方法。实例化后是否需要更新?如果不是,则跳过setter。一条好的规则是,不要把事情公之于众。从私有或默认开始,使用final保护您的数据。现在每个人都知道Person已经被正确构造,并且是不可变的。它可以自信地使用。

这很可能是你真正需要的:

代码语言:javascript
复制
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
票数 13
EN

Stack Overflow用户

发布于 2011-05-22 14:47:24

这是完全正确的,我一直都在这么做。如果它是参数检查的结果,我通常使用IllegalArguemntException。

在这种情况下,我不建议使用断言,因为它们在部署构建中被关闭,您总是希望阻止这种情况发生,但如果您的团队在启用断言的情况下执行所有测试,并且您认为在运行时丢失参数问题的可能性比抛出可能更有可能导致运行时崩溃的异常更容易接受,则断言是有效的。

而且,assert对于调用者来说更难捕获,这很容易。

您可能希望在方法的javadoc中将其列为“抛出”,并说明原因,这样调用者就不会感到惊讶。

票数 8
EN

Stack Overflow用户

发布于 2011-05-22 14:31:39

我从来不认为在构造函数中抛出异常是一种糟糕的做法。在设计类时,您应该对该类的结构有一定的了解。如果其他人有不同的想法并试图执行该想法,那么您应该相应地出错,给用户关于错误是什么的反馈。在您的情况下,您可能会考虑如下内容

代码语言:javascript
复制
if (age < 0) throw new NegativeAgeException("The person you attempted " +
                       "to construct must be given a positive age.");

其中,NegativeAgeException是您自己构造的异常类,可能会扩展另一个异常,如IndexOutOfBoundsException或类似的异常。

断言似乎也不太合适,因为您并不是在尝试发现代码中的bug。我想说,在这里使用异常终止绝对是正确的做法。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6086334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档