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

最佳答案

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

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

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

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

<小时/>

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

<小时/>

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

assert 的第二个问题是,如果断言失败,则会抛出 AssertionError 。人们普遍认为, try catch Error 及其任何子类型是一个坏主意。但无论如何,您仍然会抛出异常,尽管是以间接的方式。

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

相关文章:

java - spring + GAE对spring容器的不正确初始化

java - 使用 java 邮件 API 从网站发送自动 javamail

c++ - 在没有参数列表的情况下无效使用模板名称 'SmartArray'

java - 为什么 Java 不允许子类不能访问其父类(super class)的任何构造函数?

java - 是否有一个库或好的方法可以使 Java 上的二进制保存游戏变得更容易或更快?

java - BlackBerry 将 UIApplication 与 MainScreen 结合使用

java - 包 com.sun.xml.internal.bind.v2.model.annotation 不存在

android - 尝试在android中使用异步从url下载文件时处理异常

swift - “ fatal error :在展开可选值时意外发现nil”是什么意思?

c++ - 在 C++ 中通过重载构造函数初始化未知类型的变量