让构造函数抛出异常是一种好习惯吗? [英] Is it good practice to make the constructor throw an exception?

查看:37
本文介绍了让构造函数抛出异常是一种好习惯吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it a good practice to make the constructor throw an exception? For example I have a class Person and I have age as its only attribute. Now I provide the class as

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

推荐答案

在构造函数中抛出异常是一种不错的做法.事实上,这是构造函数指示存在问题的唯一合理方式;例如参数无效.

Throwing exceptions in a constructor is not bad practice. In fact, it is the only reasonable way for a constructor to indicate that there is a problem; e.g. that the parameters are invalid.

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

I also think that throwing checked exceptions can be OK1, assuming that the checked exception is 1) declared, 2) specific to the problem you are reporting, and 3) it is reasonable to expect the caller to deal with a checked exception for this2.

然而,明确声明或抛出 java.lang.Exception 几乎总是不好的做法.

However explicitly declaring or throwing java.lang.Exception is almost always bad practice.

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

You should pick an exception class that matches the exceptional condition that has occurred. If you throw Exception it is difficult for the caller to separate this exception from any number of other possible declared and undeclared exceptions. This makes error recovery difficult, and if the caller chooses to propagate the Exception, the problem just spreads.

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

1 - Some people may disagree, but IMO there is no substantive difference between this case and the case of throwing exceptions in methods. The standard checked vs unchecked advice applies equally to both cases.
2 - For example, the existing FileInputStream constructors will throw FileNotFoundException if you try to open a file that does not exist. Assuming that it is reasonable for FileNotFoundException to be a checked exception3, then the constructor is the most appropriate place for that exception to be thrown. If we threw the FileNotFoundException the first time that (say) a read or write call was made, that is liable to make application logic more complicated.
3 - Given that this is one of the motivating examples for checked exceptions, if you don't accept this you are basically saying that all exceptions should be unchecked. That is not practical ... if you are going to use Java.

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

Someone suggested using assert for checking arguments. The problem with this is that checking of assert assertions can be turned on and off via a JVM command-line setting. Using assertions to check internal invariants is OK, but using them to implement argument checking that is specified in your javadoc is not a good idea ... because it means your method will only strictly implement the specification when assertion checking is enabled.

assert 的第二个问题是,如果一个断言失败,那么 AssertionError 将被抛出,而人们普遍认为这是一个坏主意 尝试捕获 Error 及其任何子类型.

The second problem with assert is that if an assertion fails, then AssertionError will be thrown, and received wisdom is that it is a bad idea to attempt to catch Error and any of its subtypes.

这篇关于让构造函数抛出异常是一种好习惯吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆