这些代码语句是否等价?它们之间有什么区别吗?
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);
}
}
showException
不会重新抛出它。)showException
已经真正地处理了异常,修复了任何问题,并确保calculateArea
已经达成其目的。Exception
,或者声明您的方法也可能会抛出它。它们的不同在于处理 Exception
的责任所在。第一种仅仅是 throws Exception
,因此没有进行处理。调用该方法的代码需要处理这个 Exception
。第二种捕获并处理了 Exception
,因此调用者不必进行任何异常处理,前提是 showException()
本身不会抛出另一个异常。
是的。声明 throws Exception
的版本将要求调用代码处理异常,而显式处理异常的版本则不需要。
即:
performCalculation();
与将处理异常的负担移交给调用方相比:
try {
performCalculation();
catch (Exception e) {
// handle exception
}
FileNotFoundException
或 IOException
,因为它们可能意味着不同的事情。有一种情况我们不能使用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
由于重写的方法不能抛出额外的异常。
class A{
public void myMethod() throws Exception{
//do something
}
}
A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}
我假设你所说的“相同”,是指行为上的相同。
函数的行为可以通过以下方式确定:
1)返回值
2)抛出异常
3)副作用(例如堆、文件系统等的更改)
在这种情况下,第一种方法传播任何异常,而第二种方法不会抛出已检查的异常,并且也会吞噬大部分未经检查的异常,因此行为是不同的。
但是,如果您保证“做某事”永远不会引发异常,则行为将是相同的(尽管编译器将要求调用者处理异常,在第一个版本中)。
--编辑--
从API设计的角度来看,这两种方法在其契约方面完全不同。此外,不建议抛出类异常。尝试抛出更具体的内容以使调用者更好地处理异常。
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
}
这会抛出异常,因此调用者负责处理该异常,但如果调用者不处理异常,则可能会将其传递给 JVM,从而导致程序异常终止。
而在第二种情况下:
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
在这里,异常由被调用者处理,因此程序不会异常终止。
Try-catch 是推荐的方法。
在我看来,
Throws 关键字主要与已检查异常一起使用,以说服编译器,但它不能保证程序正常终止。
Throws 关键字将异常处理的责任委托给调用者(JVM 或另一个方法)。
Throws 关键字仅适用于已检查的异常,对于未经检查的异常,没有使用 throws 关键字的必要。