Java 中的异常

1. 不处理异常:如果代码发生异常,而没有进行 try...catch 则代码执行到此处就直接中断了,不会继续执行了。由于没有异常处理器,则这个异常被throw给了JVM,JVM处理异常的方法是:调用异常的 printStackTrace 方法,在标准输入设备中打印出上面的信息,然后JVM就shutdown了。

    public void exception(){

        int a = 1 / 0;

        System.out.println("exception end.");

    }

例如这个方法,没有进行异常处理,则JVM打印一下信息:

Exception in thread "main" java.lang.ArithmeticException: / by zero

    at org.hello.ExceptionBlock.exception(ExceptionBlock.java:13)

    at org.hello.ExceptionBlock.main(ExceptionBlock.java:8)

打印了异常发生的线程,异常类型,异常消息,调用堆栈。

        System.err.print("Exception in thread \""

                 + t.getName() + "\" ");

e.printStackTrace(System.err);

}

对于这种未经处理的异常:

① 初始化一个异常对象

② JVM在异常发生的线程上调用,

/**

* Dispatch an uncaught exception to the handler. This method is

* intended to be called only by the JVM.

*/

private void dispatchUncaughtException(Throwable e) {//e就是第一步初始化好的参数。

getUncaughtExceptionHandler().uncaughtException(this, e);

// 获得一个线程默认的异常处理器(getUncaughtExceptionHandler())。调用该异常处理器的uncaughtException方法

}

2, try...catch 处理异常

例如:

    public static void exce1(){

        int a = 0;

        try{

            int b = Integer.parseInt("0");

            a = 1 / b;

            // 由于上面的语句发生了异常,所以下面的语句没有机会执行

            System.out.println("a = 1 / b");

        }catch(Exception e){

            a = -1;

            e.printStackTrace();

        }

        // 异常在catch块中处理完毕,这条语句就可以正常执行了。

        System.out.println("exce1 end.");

    }

在这里处理了异常,是的a具有合法的值,异常catch块执行完毕之后,相当于异常成功处理了,所以下面的 System.out.println("exce1 end."); 语句也就可以正常执行了。

3. try...catch..finally

    public static void exce1(){

        int a = 0;

        try{

            int b = Integer.parseInt("0");

            a = 1 / b;

            System.out.println("a = 1 / b");

        }catch(Exception e){

//在catch块中发生了异常,所以下面的语句 不会执行,            

            a = 1/0;

            e.printStackTrace();

        }finally{

        // 这里的finally块在所有的catch块都执行完毕之后执行

            System.out.println("finally before.");

            System.out.println("finally end.");

        }

        // 由于没有catch上面的异常,则下面的语句不会被执行

        // 如果在catch块中没有异常,则下面的语句就可以正常执行

        System.out.println("exce1 end." + a);

    }

4. Throwable类

这个类其实就是JVM处理错误和异常的接口,也可以认为是JVM通知程序的一种机制。这个类及其子类都可以在 catch 语句中出现

        try {

            int b = Integer.parseInt("hello");

            int a = 123 / 0;

        }catch(ArithmeticException e){

            e.printStackTrace();

        }catch (NumberFormatException e) {

            e.printStackTrace();

        }catch(Throwable o){

            

        }finally{

            System.out.println("finally end.");

        }

而且常常是JVM来初始化这些类的对象,然后这一个一个的catch块就成了一个一个的异常处理器。当发生异常时,JVM首先初始化好异常对象,然后通过异常对象的类型和注册的异常处理器的类型对比,如果匹配则调用该处理器处理异常,最后执行finally块的代码,此时这个异常就被处理完毕。处理异常的流程:

① JVM初始化异常对象

② 匹配执行对象的异常处理器,如果没有匹配到则该异常直接抛向jvm,jvm使用默认的方式处理异常:打印异常信息,终止线程,JVM退出。

③ 如果上面的匹配到了异常处理器,最终执行完毕之后执行finally块

至此,一个抛出的异常就处理完毕了,程序可以继续向下执行了。

5. 当catch到一个异常时,如何处理

在Throwable类的描述,举了一个例子:

try {

    // 比如DAO中的数据库操作,出现异常

lowLevelOp();

} catch (LowLevelException le) {

    // 初始化一个自定义的异常,将其抛到业务层。

    // 业务层,根据业务逻辑来处理该异常。

throw new HighLevelException(le); // Chaining-aware constructor

}

在分层的架构下:例如WEB MVC中,如果一层抛出了异常但是没法处理(常常是不知道如何处理,或者说在这个处理不合适)那就封装一层往上抛。

 

6. 异常的分类

checked异常和unchecked异常

Exception类及其子类(除了java.lang.RuntimeException类)都是checked异常,当我们throw一个这种类型的异常时必须处理,而java.lang.RuntimeException类,则是unchecked异常,这种类型的异常可以不用强制处理:

public class TestException {

    public static void main(String[] args) {

        String res = "";

        res = findUserName("hello");

        System.out.println(res);

        

        res = findUserName("");

        System.out.println(res);

        

//        try {

//            res = findPassword("");

//        } catch (PasswordIsInvalid e) {

//            e.printStackTrace();

//        }

    }

    

    public static String findUserName(String params){

        

        if(null == params || "".equals(params)){

// UserNameIsInvalid是unchecked的异常,所以不需要处理

            throw new UserNameIsInvalid("参数无:-D");

        }

        

        return "xxx";

    }

    

    public static String findPassword(String params) throws PasswordIsInvalid{

        

        if(null == params || "".equals(params)){

// 这里抛出了一个checked异常,所以要进行处理,所以要在方法上throws这个异常

            throw new PasswordIsInvalid("参数无:-D");

        }

        

        return "xxx";

    }

}

 

@SuppressWarnings("serial")

class PasswordIsInvalid extends Exception{

    public PasswordIsInvalid(String message) {

        super(message);

    }

}

 

@SuppressWarnings("serial")

class UserNameIsInvalid extends RuntimeException{

    public UserNameIsInvalid(String message) {

        super(message);

    }

}

你可能感兴趣的:(java)