异常处理

                    异常处理 

运行下面的程序,你将会看见异常的出现:

 

代码
public class ExcepDemo {
public int division(int a,int b) {
return a / b;
}
}

class Test {
public static void main(String[] args) {
ExcepDemo
= new ExcepDemo ();
System.out.println(e.division(
5,0));
}
}

 

 

Java程序在执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给java运行时系统,这个过程称为抛出(throw)异常

当java运行时系统接受到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程成为捕获(catch)异常。

如果java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的java程序也将退出。

 

代码
public class Excep {
public int division(int a,int b) {
return a / b;
}
}

class Test {
public static void main(String[] args) {
Excep e
= new Excep();
System.out.println(e.division(
5,0));
// 由于上一步传入参数0,引发异常,导致java运行时系统终止,相应的java程序也将退出。
System.out.println("finish"); // 不能输出
}
}

try/catch/finally语句。将可能引发异常的代码放到try语句当中,然后在catch语句当中对所引发的异常条件进行处理。finally语句中放始终要执行的语句,例如上面的System.out.println("finish");

 

 

代码
public class Excep {
public int division(int a,int b) {
return a / b;
}

public int method(int a ,int b) {
return division(a,b);
}
}

class Test {
public static void main(String[] args) {
Excep ex
= new Excep();
try {
ex.method(
5,0);

}
catch(Exception e) {
System.out.println(
"除数不能为0");
}
finally{
System.out.println(
"finally");
}
System.out.println(
"finish");
}
}

// output:

 

除数不能为0

finally

finish

既然都能输出,那么为什么还要使用finally呢?

 

代码
class Excep {
public int division(int a,int b) {
return a / b;
}

public int method(int a ,int b) {
return division(a,b);
}
}

class Test {
public static void main(String[] args) {
Excep ex
= new Excep();
try {
ex.method(
5,1);
return;// 没有发生异常之前,在返回之前,肯定要去执行finally的语句
} catch(Exception e) {
System.out.println(
"除数不能为0");
}
finally {
System.out.println(
"finally");
}
System.out.println(
"finish");
}
}

 

只有finally输出,没有除数不能为0和finish的输出。

 

一旦try中引发异常,那么程序就会跳转到catch中去执行。执行完catch之后,然后会继续执行catch下面的代码。

当然finally也不是在任何时候都会执行,当程序退出时就不执行了。

 

代码
public class Excep {
public int division(int a,int b) {
return a / b;
}

public int method(int a ,int b) {
return division(a,b);
}
}

class Test {
public static void main(String[] args) {
Excep ex
= new Excep();
try {
ex.method(
5,0);
}
catch(Exception e) {
System.out.println(e.toString());
System.exit(
0);
}
finally{
System.out.println(
"finally");
}
}
}

 

用异常本身的方法打印异常信息 

 

catch(Exception e) {
//System.out.println("除数不能为0");// 程序员自己编写的。
System.out.println(e.getMessage());// 获取异常本身的详细信息。
}

toString()  获取throwable的一个简短的描述

catch(Exception e) {
System.out.println(e.toString());
// 获取throwable的一个简短的描述。
}

 

 

Exception 重写了toString方法。e.toString()打印的异常信息比getMessage()详细些。

printStackTrace 可以将异常在代码中发生的一个位置打印出来。

 

catch(Exception e) {
e.printStackTrace();
//将异常在代码中发生的一个位置打印出来
}

 

这样就方便管理人员进行维修和处理。和java虚拟机打印的异常是相似的。

 

捕获异常可以在一开始就捕获。

 

public class Excep {
public int division(int a,int b) {
try {
return a / b;
}
catch(ArithmeticException e) {
e.printStackTrace();
        // return 0;
}
}
}

上面的代码对吗?

 

不对,缺少返回值。因为return a/b确实是返回了一个整型,但是这里其实是分两步执行的。首先执行a/b,再返回,但是如果这里a / b引发异常,程序跳转到catch语句当中,不能return 结果了。所以我们应该手动的去返回一个整型。可以将catch块中的注释打开就可以了。

抛出异常就是抛给它的调用者,调用者也应该抛出异常。

 

public class Excep {
public int division(int a,int b) throws Exception{
return a / b;
}

public int method(int a ,int b) throws Exception{
return division(a,b);
}
}

那么如果要在main方法中使用,main方法也要throws Exception

 

main()的调用者java运行时系统,打印异常发生的轨迹,然后终止程序的运行。

编写程序的时候为了节省时间,可以在main函数当中直接把异常抛给java运行时系统。但是在实际编写代码的时候,我们最好还是将异常自行捕获到,然后在自己的代码当中自己处理。得到准确的信息给用户或管理者。

捕获异常时应该注意顺序(先小后大

 

代码
public static void main(String[] args) {// 抛给main()的调用者java运行时系统
Excep ex = new Excep();
try {
ex.method(
5,0);
}
catch(ArithmeticException e1) {
System.out.println(e1.toString());
}
catch(Exception e2) {
System.out.println(e2.toString());
}
}

 

捕捉到了异常对象之后直接抛出

public int division(int a,int b) throws Exception {
try {
return a / b;
}
catch(Exception e) {
e.printStackTrace();
throw e;
}
}

抛出一个新的异常对象

public int division(int a,int b) throws Exception {
try {
return a / b;
}
catch(Exception e) {
e.printStackTrace();
throw new Exception("不能被0除");//抛出一个新的异常对象。
}
}

 

                      自定义异常类

所有的异常类必须都从Exception派生,Exception类是所有异常类的基类。

class DiviserIsMinusException extends Exception{ // 自定义异常类。所有的异常类必须都从Exception派生,Exception类是所有异常类的基类。
DiviserIsMinusException(String str){
super(str);// 调用基类的构造方法
}
}
使用自定义异常类

代码
public class Excep {
public int division(int a,int b) throws ArithmeticException,DiviserIsMinusException {
if(b<0) {
throw new DiviserIsMinusException("diviser can't be minus");
}
return a / b;
}

public int method(int a ,int b) throws ArithmeticException,DiviserIsMinusException {
return division(a,b);
}

}

如果父类中的方法抛出多个异常,则子类中的覆盖方法要么抛出相同的异常,要么抛出异常的子类,但不能抛出新的异常(注:构造方法除外)。

我们可以在方法声明时,声明一个不会抛出的一场,java编译器就会强迫方法的使用者对异常进行处理。这种方法通常用于abstractbase clas和interface中。

posted @ 2010-12-21 15:49  meng72ndsc  阅读(272)  评论(0编辑  收藏  举报