Java中'throws'语句的目的是什么?

时间:2011-07-01 22:52:26

标签: java exception throws

我只是在学习java,但似乎最后调用堆栈开头的大多数方法都只有声明'throws Exception'。我错过了这个使它有用的陈述有什么好处?

又一个例子。在编写了一些代码之后,我决定使用其他java库中的类来重构我的一个类。结果,这个类的一半方法不仅在声明中获得了另外5个异常,而且大约是我所有其他代码的一半 - 直到我决定我最好写'抛出异常'并且不关心关于。可能我只是使用异常错误?

重要编辑

我的问题不在于该声明的作用 - 从文档中可以看出这一点。我实际上想知道为什么语言设计师决定使这个陈述变得必要。

7 个答案:

答案 0 :(得分:3)

Java的异常方法是让方法调用者知道失败条件,因此被迫处理它们或者确认异常不是通过调用者方法的重复throws语句来处理的。或者换一种方式,知道抛出什么异常是方法签名的一部分,因此是显式抛出语句。

对于在正常操作过程中不会发生的故障情况,有两种特殊的异常:RuntimeException和Error。这些异常的子类不需要在throws子句中显式声明或由调用者捕获。

值得注意的是,使用“throws Exception”是生产代码中的草率编程,因为它不会告诉调用者该方法有关实际故障情况的任何信息。我唯一一次考虑使用泛型“throws Exception”声明而不是枚举实际的异常类型,就像单元测试这样的情况,其中明确声明失败案例没有用处。

答案 1 :(得分:3)

虽然其他答案是正确的,但我认为他们以你提出的方式错过了目的。

throws语句是如何创建异常堆栈跟踪的。 java中没有太大的魔力 - 它不是创建异常的一些底层系统之谜,它只是一个“Throw”语句,因此任何堆栈跟踪中的最后几个条目都可能被抛出。

它不仅仅是最后一个,因为在许多情况下,异常处理包含以下内容:

try {
     do something that might cause an exception
catch(ExpectedException e) {
     throw new DifferetnException(e);
}

这使您可以更改它的类型,或者添加更好的文本描述,甚至可以在重新抛出其他异常时处理一些异常。

因此,它通常是由“投掷”声明引起的最后几个级别(可能是一些中间级别)。

答案 2 :(得分:1)

它向班级用户表明他们必须处理特殊情况。 throws子句的主题告诉用户这些异常情况是什么。

如果异常是经过检查的异常,编译器将在用户代码中强制执行try / catch块;未经检查的异常不需要catch块来处理。在这种情况下,异常将继续冒出调用堆栈,直到它被处理或程序退出。

答案 3 :(得分:1)

经过大量关于异常和最佳实践的阅读后,我意识到我犯了一个错误,使用Exception类来处理编程错误 - 我在字面上检查每个方法 - 我应该使用RuntimeException,这是不需要检查。在重构我的代码之后,我只在必要的地方得到了“抛出”语句,现在它整洁干净。

答案 4 :(得分:0)

它让你意识到可能出现的问题,并强迫你处理它们或明确说你不是。

答案 5 :(得分:0)

在Java中,有 Checked Exceptions Runtime Exceptions

选中的异常只能在明确声明它们的方法中出现。 运行时异常可以出现在代码中的任何位置,而不必声明。 throws IOException子句声明在此方法中可能会发生IOException。

运行时异常是扩展RuntimeException类的那些。所有其他人都是已检查的例外

异常实际上是由方法中的throw new IOException(...)等语句引发的。

答案 6 :(得分:-1)

引发异常。异常将向后传递给函数进入堆栈,直到它被catch块捕获,它可以处理它。

当throw关键字放在方法声明中时,它表示对该方法的调用可能会生成异常。例如:

public void methodFoo (int val) throws IllegalArgumentException  {
    if (val <0) throw new IllegalArgumentExecption();
}

表示methodFoo可以引发IllegalArgumentException类型的异常。 当您调用这样的方法时,通常使用以下try / catch块语句:

try{
   methodFoo(int param);

}catch (IllegalArgumentException e){
       //if any method call inside methodFoo will raise such exception the execution flow of the program will be interrupted and the execution restart from the first catch block that intercept that execption
}

这种方法的“好处”在于,使用此功能,您不必检查方法的返回值,以确保方法调用成功。在C语言中,您通常会执行以下操作:

int ret = methodFoo();

if (ret == null){
     //error
}