java 异常详解 代码讲解

异常:当程序运行时,发生了不可预期的事件导致程序中断就是异常。异常发生时该怎么处理呢,c语言中,发生异常时返回某一数值作为执行状态。在java中提供了优秀的异常捕获机制。

先来看一下异常有哪些种类,java中异常的父类时Throwable,其子类是Error和Exception。Error类代表运行时环境发生的错误,程序中是不用捕获这类异常的。Exception类中的异常是可以捕获的,Exception类的子类包括了:RuntimeException运行时异常Checked Exception受检异常,从https://blog.csdn.net/xialei199023/article/details/63251277盗了这张图,借用一下,里面有所有类的继承关系


程序中难免会出现异常,应该秉持两种规则:不忽视和不丢弃;一般来讲当程序出现异常时我们通常会采用一下几种方式来处理:

1.捕捉并处理异常,防止它传播给调用端;进而遏制异常的进一步传播。

2.捕捉,并再次原样抛出异常给调用端,将异常原样throw。

3.捕捉,然后抛出一个新异常给调用端,确保新抛出的异常包含原有异常信息,但可进一步封装,调用throw将新异常 抛出。

4.不捕捉,任由它传播给调用端,并且该函数会马上中断,不会继续执行该函数的后续语句。

对于第一种处理操作是不推荐的,因为捕捉完不做处理,是很危险的,例如如下代码,不着玩异常,就空着不做处理,程序有可能因为这种异常返回错误结果:

        try {
            result = Integer.parseInt(str);
        } catch(NumberFormatException nfex) {
        }

对于第二种方式是合适的(以下代码是第二种方式),其他第三第四种是可以的,只是上述第一种方式不建议。异常处理里面啥也没有,程序将继续执行。

        try {
            result = Integer.parseInt(str);
        } catch(NumberFormatException nfex) {
            throw new Exception("asdad");
        }

我们要知道一个知识点,当你没有捕获异常时,异常将导致程序结束。当你捕获异常时程序将继续往下执行。

首先看一下如下代码将抛出的异常:

public class ExceptionDemo {
    public static void main(String[] args) {
        try {
            System.out.println(string2Int("asdadads"));
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 将字符串转成整数
     * @param str
     * @return
     */
    public static int string2Int(String str) {
        int result = 0;
        result = Integer.parseInt(str);
        return result;
    }
}

打印结果:

For input string: "asdadads"
java.lang.NumberFormatException: For input string: "asdadads"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:580)
	at java.lang.Integer.parseInt(Integer.java:615)
	at ExceptionDemo.string2Int(ExceptionDemo.java:42)
	at ExceptionDemo.main(ExceptionDemo.java:16)

可以看到,是报异常了,有异常信息,和异常的代码流。那如何处理异常让程序正常返回并不影响后续执行呢?请看如下代码:

public class ExceptionDemo {
    public static void main(String[] args) {
        System.out.println(string2Int("asdadads"));
    }

    @SuppressWarnings("finally")//注解表示忽略finally语句块中的警告
    public static int string2Int(String str) {
        int result = 0;
        try {
            result = Integer.parseInt(str);
        } catch(NumberFormatException nfex) {
            //对异常进行处理,一般是两种用途:日志和对异常情况的处理
            System.out.println(nfex.getMessage());
        } 
        return result;
    }
}
执行结果是:
For input string: "asdadads"
0

可以看到与上一程序的区别在于这个程序在函数内部就处理了异常,处理完异常后程序不中断,继续执行,也不用抛出异常,外层调用该函数的地方也不用作异常捕获处理。程序具有较强的健壮性。

好的我们继续来看一个异常中的问题,异常覆盖,啥叫异常覆盖呢,请看以下程序,您觉得结果是什么,思考一分钟,然后揭晓答案:

public class ExceptionDemo {
    public static void main(String[] args) {
        try {
            System.out.println(testCoverException("asdadads"));//这输入是会报异常的
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * 将字符串转成整数
     * @param str
     * @return
     * @throws Exception
     */
    @SuppressWarnings("finally")
    public static int testCoverException (String str) throws Exception {//申明需要抛出的异常
        int result = 0;
        try {
            result = Integer.parseInt(str);
        } finally {
            throw new Exception("amazing");
        }
    }

}

答案是:打印amazing。

你会想为什么是amzing,而不抛出NumberFormatException异常信息呢。可以看到该程序是会抛出两个异常的,确实,程序执行抛出了两个异常,一个是NumberFormatException一个是Exception("amzing")但是异常是会被覆盖掉的,最终程序只抛出一个异常,后面的异常会覆盖前面的异常。回到程序,在出现NumberFormatException后因为没有catch语句做异常处理,这边默认异常处理为空,继续执行finally语句抛出新异常,覆盖老异常。对于这种异常覆盖的解决将在下一篇中说明。

//    try和catch可以连用,try-catch- finally可以连用,这是众所周知的,但是try、catch、finally这三个关键字

//    却不能单独使用,如果在程序中只想try而不去catch也是可以的,但是try的后面必须跟有finally。


     * 我们知道在java中,无论是return还是抛出异常,都会导致方法的结束。但是java中finally语句又必须执行,
     * 所以finally语句的执行时机应该是在try语句中的return语句之前,或者catch语句中throw语句执行之前。
     * 不然,无论是return语句执行,还是throw语句执行,都将导致finally语句无法得到执行。又由于在finally
     * 语句中,书写了return语句,就是这么个return语句,将导致方法的提前结束,因而无论是try中的return语句,
     * 还是catch中的throw语句,都将失去执行的机会,仿佛被覆盖掉了一般。











猜你喜欢

转载自blog.csdn.net/u013276277/article/details/80329743