java - 让构造函数抛出异常是一种好习惯吗?

标签 java exception constructor

让构造函数抛出异常是个好习惯吗? 例如,我有一个类 Person 并且我有 age 作为它的唯一属性。现在 我提供的类(class)为

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;
  }
}

最佳答案

在构造函数中抛出异常并不是一个坏习惯。事实上,构造函数表明存在问题是唯一合理的方式;例如参数无效。

我也认为抛出 checked 异常是可以的1,假设检查的异常是 1) 声明的,2) 特定于您报告的问题,并且3) 期望调用者处理 this2 的已检查异常是合理的。

但是,显式声明或抛出 java.lang.Exception 几乎总是不好的做法。

您应该选择一个与已发生的异常情况相匹配的异常类。如果您抛出 Exception,调用者很难将此异常与任何数量的其他可能已声明和未声明的异常区分开来。这使得错误恢复变得困难,如果调用者选择传播异常,问题就会蔓延。


1 - 有些人可能不同意,但 IMO 这种情况与在方法中抛出异常的情况没有本质区别。标准检查与未检查建议同样适用于这两种情况。
2 - 例如,如果您尝试打开不存在的文件,现有的 FileInputStream 构造函数将抛出 FileNotFoundException。假设 FileNotFoundException 是一个已检查的异常3 是合理的,那么构造函数就是最适合抛出该异常的地方。如果我们在第一次(比如)readwrite 调用时抛出 FileNotFoundException,这可能会使应用程序逻辑更加复杂.
3 - 鉴于这是已检查异常的激励示例之一,如果您不接受这一点,您基本上是在说所有异常都应该未经检查。那是不切实际的……如果你打算使用 Java。


有人建议使用 assert 来检查参数。这样做的问题是,可以通过 JVM 命令行设置打开和关闭对 assert 断言的检查。使用断言来检查内部不变量是可以的,但是使用它们来实现在你的 javadoc 中指定的参数检查不是一个好主意......因为这意味着你的方法只会在启用断言检查时严格实现规范。

assert 的第二个问题是,如果一个断言失败,那么 AssertionError 将被抛出,并且普遍认为这是一个坏主意 try catch Error 及其任何子类型。

关于java - 让构造函数抛出异常是一种好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6086334/

相关文章:

c++ - wxWidgets:关闭自定义模式对话框时出现内存错误

c++ - 如何捕获一般异常并显示其派生的 what()

c++ - 类不存在默认构造函数

c++ - 带默认参数的构造函数

java - 我可以在 TableView 中使用 CheckBoxTableCell 作为让用户选择多行的方法吗?

java - 事务回滚之前的事务

java - Java 中的异常(可恢复与致命)

c# - 在构造函数中传递对 'this' 的引用

java - 为什么 Spring Batch 为每个线程使用 1 个数据库连接?

java - SSIS:通过 Linux 将 ispac 转换为 dtsx 或以编程方式提取文件