Java中异常规范的好处是什么?

5

我从C++转向Java。 在Java和C++中,我们都有可能进行异常的指定。它的写法如下:

void function_name() throw(Exception)
{
  ...
  if (error) 
  {
    throw Exception("Error");
  }
  ...
}

据我所知,在C++中编写异常规范被认为是一种不好的做法。与C++不同,在Java中我们必须这样做。因此,我的问题是: 在Java中编写异常规范有什么好处?

2
据我所知,这甚至比不良实践更糟糕,现在已经被弃用了(在C++中)。 - Xaqq
4
没有异常规范是一种在函数签名中添加可能抛出的异常类型的方式,以使内容更加易于理解。 - Jean-Baptiste Yunès
1
在C++中使用IT是不好的实践,因为它们已经被过于标准化并与编译器集成得不同。当指定异常时,不同的编译器可能会产生不同的行为。请参见:https://msdn.microsoft.com/en-us/library/wfa0edys.aspx - Jean-Baptiste Yunès
1
@Zefick 因为谷歌在其传统代码库中没有使用异常并不意味着它们是不好的。异常是一种很好地利用RAII的好东西。 - Xaqq
除了 std::throw()noexcept 之外的异常规范在编译时无法跟踪。结果是编译器生成的开销,程序员应该考虑这一点(换句话说,这些是无用的)。 - user2249683
显示剩余6条评论
2个回答

5

在方法签名中,您必须指定仅已检查的异常(Exception类的子类)。未经检查的异常(RuntimeException类的子类)不需要被指定。

在方法签名中指定异常是Java语言语义所定义的固有实践。但是关于这个问题也存在很多争议。有些团队和项目甚至认为它是不良实践,只使用未经检查的异常。

通常,作为一种良好的实践,当您将其定义为方法的一部分契约时,应抛出一个已检查的异常,即方法调用者必须意识到某些特定(可能且可恢复的)类型的错误,并且要么捕获并处理它,要么将其传递给调用堆栈。未经检查的异常通常表示方法代码中的一些内部错误,因此不需要被捕获。


1
你必须在签名中指定已检查的异常,否则会出现编译错误。 - Mick Mnemonic
@MickMnemonic 谢谢,已更正“specify”为“throw”。 - Forketyfork

0

Java 中没有 利润,异常规范是强制性的。Java 的类型系统比 C++ 更加强大。在 C++ 中,异常规范是可选的,而 Java 设计者认为异常是程序设计的重要部分,因此他们决定在函数可能抛出任何异常时强制执行异常规范。这有时会引起争议,但这是一种语言设计选择。异常是调用契约的一部分。


异常规范仅对不是RuntimeException子类的异常强制执行。 - Mick Mnemonic
比C++更强的类型系统。这是一个大胆的说法(我个人不同意)。我认为C++尝试使用异常规范是失败的,而且在我看来,Java版本也存在同样的问题。随着底层代码随着时间的推移而发生变化,出现了新的不同异常,规范逐渐演变成更一般的异常,结果规范变得越来越弱(更一般),并且随着时间的推移,在任何经常更新的代码上都会变得越来越弱。因此,在我看来,它们是无用的。 - Martin York

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接