← 返回首页
JavaSE系列教程(五十八)
发表时间:2020-02-05 16:14:16
Java的异常处理机制。

Java的异常处理是由try、catch与finally等3个关键字所组成的程序块。

Java异常机制用到的几个关键字:try、catch、finally、throw、throws。

1)try      -- 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。

2)catch   -- 用于捕获异常。catch用来捕获try语句块中发生的异常。

3)finally  -- finally语句块总是会被执行。通常执行一些资源释放的操作(如数据库连接释放、网络连接和磁盘文件的关闭等等)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。

4)throw   -- 用于抛出异常。

5)throws -- 用在方法签名中,用于声明该方法可能抛出的异常。主方法上也可以使用throws抛出。如果在主方法上使用了throws抛出,就表示在主方法里面可以不用强制性进行异常处理,如果出现了异常,就交给JVM进行默认处理,则此时会导致程序中断执行。

这五个关键字的关系如下图所示:

异常处理的执行流程图如下所示:

抛出异常后通常可用两种方法来处理,一种是交由Java默认的异常处理机制做处理。也就是使用关键字throws 声明抛出异常。另一种处理方式是用自行编写的try-catch-finally块来捕捉异常。自行编写程序代码来捕捉异常最大的好处是,可以灵活操控程序的流程,且可做出最适当的处理。

1.使用try-catch-finally捕获异常

try-catch-finally异常处理格式之中可以分为三类: (1)try{}…catch{} (2)try{}…catch{}…finally{} (3)try{}…finally{}

其中第二种方式使用频率最高。 例如,以下是加载一个类的实现代码:

public class Demo {

    public static void main(String[] args) {

        try{
           Class.forName("com.test.HelloWorld");
        }catch(Exception ex){
            ex.printStackTrace();
        }finally{
            System.out.println("测试类加载完毕!");
        }
    }
}

假设com.test.HelloWorld这个类不存在,则抛出以下异常:
java.lang.ClassNotFoundException: com.test.HelloWorld
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at encapsulationdemo.Demo.main(Demo.java:41)
测试类加载完毕!

我们在catch代码块里使用ex.printStackTrace();打印出异常堆栈信息。其中,ex是异常对象。

我们也可以使用关键字throw ,抛出一个异常对象。例如:

public class Demo {

    public static void main(String[] args) {

        try {
            System.out.println("程序开始..");
            for(int i=0;i<10;i++) {
                if(i%3==0) {
                    throw new Exception("自己抛出的异常");
                }
            }
            System.out.println("程序即将结束...");
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            System.out.println("程序执行完毕!");
        }
    }
}

当循环到3的倍数时,抛出异常:
程序开始..
java.lang.Exception: 自己抛出的异常
    at encapsulationdemo.Demo1.main(Demo.java:43)
程序执行完毕!

2.使用throws声明抛出异常

我们通过改写第一个程序,把加载类的过程抽象成一个方法,代码如下:

public class Demo {

    public static void initMyClass() throws ClassNotFoundException{
        Class.forName("com.test.HelloWorld");
    }

    public static void main(String[] args) throws Exception {

       Demo.initMyClass();
    }
}

假设com.test.HelloWorld这个类不存在,则抛出以下异常:
Exception in thread "main" java.lang.ClassNotFoundException: com.test.HelloWorld
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at encapsulationdemo.Demo.initMyClass(Demo.java:38)
    at encapsulationdemo.Demo.main(Demo.java:43)

这里由于Class.forName方法会抛出一个受检查性异常,必须捕获异常。如果不想使用try-catch-finally自己捕获,则该方法必须声明抛出异常。又由于主方法调用了这个方法时也没有处理异常,所以主方法也必须声明抛出异常,最终这个异常交给JVM去捕获处理。声明抛出异常使用关键字throws.

小结:

1.Java的异常处理用到五个关键字:try、catch、finally、throw和throws.

2.Java的异常处理有两种方式:1)使用try-catch-finally自己捕获处理异常 2)使用关键字throws声明抛出异常。