这些代码声明是否相同? 它们之间有什么区别吗?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
答案 0 :(得分:136)
是的,这是一个巨大的差异 - 后者吞下了异常(无可否认地显示它),而第一个将让它传播。 (我假设showException
不会重新抛出它。)
因此,如果您调用第一个方法并且“执行某些操作”失败,则调用者将必须处理该异常。如果你调用第二种方法并且“做某事”失败,那么调用者根本不会看到异常......这通常是一件坏事,除非showException
真正处理例外,修复了错误,并确保calculateArea
达到了目的。
你可以告诉它,因为你不能在没有 自己捕捉Exception
或宣布你的方法可能的情况下调用第一种方法扔掉它。
答案 1 :(得分:17)
第一个throws Exception
,因此调用者需要处理Exception
。第二个在内部捕获并处理Exception
,因此调用者不必进行任何异常处理。
答案 2 :(得分:14)
是。声明throws Exception
的版本将需要调用代码来处理异常,而显式处理它的版本则不会。
即,简单地说:
performCalculation();
VS。将处理异常的负担转移给调用者:
try {
performCalculation();
catch (Exception e) {
// handle exception
}
答案 3 :(得分:5)
是的,它们之间存在很大差异。在第一个代码块中,您将异常传递给调用代码。在第二个代码块中,您自己处理它。哪种方法正确完全取决于您正在做什么。在某些情况下,您希望您的代码处理异常(例如,如果找不到文件并且您想要创建它),但在其他情况下,您希望调用代码处理异常(找不到文件)他们需要指定一个新的或创建它。
一般来说,您也不希望捕获一般异常。相反,您只想捕捉特定的内容,例如FileNotFoundException
或IOException
,因为它们可能意味着不同的内容。
答案 4 :(得分:3)
有一个特殊情况我们不能使用throws,我们必须使用try-catch。 有一条规则“重写的方法不能抛出除父类抛出之外的任何额外异常”。如果有任何额外的异常应该使用try-catch处理。 请考虑此代码段。 有一个简单的基类
package trycatchvsthrows;
public class Base {
public void show()
{
System.out.println("hello from base");
}
}
它是派生类:
package trycatchvsthrows;
public class Derived extends Base {
@Override
public void show() {
// TODO Auto-generated method stub
super.show();
Thread thread= new Thread();
thread.start();
try {
thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// thread.sleep(10);
// here we can not use public void show() throws InterruptedException
// not allowed
}
}
当我们必须调用thread.sleep()时,我们被迫使用try-catch,这里我们不能使用:
public void show() throws InterruptedException
因为重写的方法不能引发额外的异常。
答案 5 :(得分:1)
我认为“相同”是指行为。
函数的行为可以通过以下方式确定:
1)返回值
2)抛出异常
3)副作用(即堆,文件系统等的变化)
在这种情况下,第一种方法传播任何异常,而第二种方法不抛出任何检查异常,并且吞下大多数未经检查的异常,因此行为不同。
但是,如果您保证“执行某些操作”从不抛出异常,那么行为将是相同的(尽管编译器将要求调用者在第一个版本中处理异常)
- 编辑 -
从API设计的角度来看,这些方法在合同中完全不同。此外,不建议抛出类异常。尝试抛出更具体的内容以允许调用者更好地处理异常。
答案 6 :(得分:1)
如果抛出异常,子方法(覆盖它)应该处理异常
示例:
class A{
public void myMethod() throws Exception{
//do something
}
}
A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}
答案 7 :(得分:0)
此方法的调用者需要捕获此异常或声明它在其方法签名中重新抛出。
private void calculateArea() {
try {
// Do something
} catch (Exception e) {
showException(e);
}
}
在下面的try-catch块示例中。这种方法的调用者不必担心处理异常,因为它已经被处理过了。
{{1}}
答案 8 :(得分:0)
您希望调用者多次处理异常。假设你有一个调用者调用一个调用另一个方法调用另一个方法的方法,而不是让每个方法处理异常,你可以在调用者处理它。除非,当该方法失败时,您希望在其中一个方法中执行某些操作。
答案 9 :(得分:0)
private void calculateArea() throws Exception {
....do something
}
这会引发异常,因此调用方负责处理该异常,但是如果调用方不处理异常,则可能会将其交给jvm,这可能导致程序异常终止。
在第二种情况下:
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
这里异常是由被调用者处理的,因此程序不会异常终止。
推荐使用尝试捕获。
IMO,
Throws关键字通常与Checked异常一起使用以说服 编译器,但不能保证程序正常终止。
Throws关键字将异常处理的职责委托给
调用者(JVM或其他方法)。
Throws关键字仅对于已检查的异常是必需的,对于未检查的异常是必需的 例外,没有使用throws关键字。