这些代码语句是否等效?它们之间有什么区别吗?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
这些代码语句是否等效?它们之间有什么区别吗?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Answers:
是的,两者之间存在巨大差异-后者吞下了异常(诚然显示了此异常),而第一个则允许其传播。(我假设showException
不会将其扔掉。)
因此,如果您调用第一个方法而“执行某些操作”失败,则调用者将不得不处理该异常。如果调用第二种方法和“做什么”失败,则调用者不会看到在所有的例外......通常是一件坏事,除非showException
有真正处理的异常,无论固定错了,一般做肯定这calculateArea
已经达到了目的。
您可以讲这个,因为你不能调用的第一个方法没有任何追赶Exception
自己或者宣告你的方法可能把它太。
首先throws Exception
,因此呼叫者需要处理Exception
。第二个在Exception
内部捕获并处理,因此调用方不必执行任何异常处理。
在一种特殊情况下,我们不能使用throw,而必须使用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
因为重写的方法不能引发额外的异常。
我认为“相同”是指行为。
函数的行为可以通过以下方式确定:
1)返回值
2)抛出异常
3)副作用(例如,堆,文件系统等的更改)
在这种情况下,第一种方法传播任何异常,而第二种方法则不引发任何已检查的异常,并且也吞没大多数未检查的异常,因此行为是不同的。
但是,如果保证“执行某些操作”绝不会引发异常,则行为将是相同的(尽管在第一个版本中,编译器将要求调用者处理该异常)
- 编辑 -
从API设计的角度来看,这些方法的契约完全不同。另外,不建议抛出类Exception。尝试抛出更具体的内容,以使调用方更好地处理异常。
private void calculateArea() throws Exception {
....do something
}
这会引发异常,因此调用方负责处理该异常,但是如果调用方不处理异常,则可能会将其提供给jvm,这可能导致异常终止程序。
而在第二种情况下:
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
在这里,异常是由被调用者处理的,因此程序不会异常终止。
尝试捕获是推荐的方法。
海事组织
Throws关键字通常与Checked异常一起使用,以说服编译器,但不能保证程序正常终止。
Throws关键字将异常处理的责任委托给
调用方(JVM或其他方法)。
Throws关键字仅对于已检查的异常是必需的,对于未检查的异常,则不使用throws关键字。