moc 发表于 2018-12-27 10:00:30

Java-024异常

本帖最后由 moc 于 2019-1-6 20:56 编辑

1、异常的概念及体系
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
三种类型的异常
        ① 错误:   错误是严重的异常,它脱离程序员控制。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
        ② 检查性异常:   由用户输入错误或问题引起的异常,这是程序员无法预见的。例如打开一个不存在文件,这些异常在编译时不能被简单地忽略。
        ③ 运行时异常:   运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
异常体系
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。
在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。
Java异常层次结构图如下图所示:
Throwable      所有异常类型的超类
        |--Error      严重问题,程序员不处理。
        |--Exception
                |--RuntimeException      运行期异常,我们需要修正代码
                |--非RuntimeException      编译期异常(如IOException),必须处理的,否则程序编译不通过
2、异常的处理
1. JVM的默认处理
        JVM会中断程序,并把异常的名称,原因,位置等信息输出在控制台。
2. try方式
格式:
        try { 可能出现问题的代码;}
                catch(异常名 变量) { 针对问题的处理;        }
                finally { 释放资源; }
与python处理异常的方式一致,try后的语句体为异常监控区域,catch后的为捕获处理语句,finally后的为总会被执行的语句。
注意:
        ① try里面的代码越少越好,一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配;
        ② 一旦有匹配的,就执行catch里面的处理,catch里面必须有内容,然后结束了try...catch;
        ③ finally项不是必须的,可以没有。
        ④ catch子句可以多个,需注意顺序问题,先小后大,即先子类后父类;
        ⑤ JDK7后,可以catch(异常名1 | 异常名2 | ...变量 ) 对多种异常进行统一处理。
3. throws方式
        对可能产生的异常,自己并不处理,而是向外抛出异常,交由调用它的类或方法去处理。
格式:
                throws 异常类名
        ① 尽量不要在main方法上抛出异常,否则编译器会按默认方式处理;
        ② 编译期异常抛出,将来调用者必须处理; 运行期异常抛出,将来调用可以不用处理;
throws和throw的区别:
throws:
        ① 用在方法声明后面,跟的是异常类名;
        ② 可以跟多个异常类名,用逗号隔开;
        ③ 表示抛出异常,由该方法的调用者来处理;
        ④ throws表示出现异常的一种可能性,并不一定会发生这些异常。
throw:
        ① 用在方法体内,跟的是异常对象名;
        ② 只能抛出一个异常对象名;
        ③ 表示抛出异常,由方法体内的语句处理;
        ④ throw则是抛出了异常,执行throw则一定抛出了某种异常。
public static void method() {
        int a = 10;
        int b = 0;
        if (b == 0) {
                throw new ArithmeticException();
        } else {
                System.out.println(a / b);
        }
}catch遇上return:
如果catch里面有return语句,请问finally里面的代码还会执行吗? 如果会,请问是在return前,还是return后?
        会, 前,如果是catch里有System.exit(0),就不会执行finally,而是直接退出程序。
public static int getInt() {
        int a = 10;
        try {
                System.out.println(a / 0);
                a = 20;
        } catch (ArithmeticException e) {
                a = 30;
                return a;
        /* return a在程序执行到这一步的时候,这里不是return a而是return 30;这个返回路径就形成了。
       * 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
       * 再次回到以前的返回路径,继续走return 30;
       */
        } finally {
                a = 40;
                //return a;//如果还有就会返回40
        }
}3、异常方法
    在try里面发现问题后,jvm会帮我们生成一个异常对象,然后把这个对象抛出,和catch里面的类进行匹配。
如果该对象是某个类型的,就会执行该catch里面的处理信息。
异常中的几个方法:
public String getMessage()-------------->异常的消息字符串               
public String toString()    ----------------->返回异常的简单信息描述
        此对象的类的 name(全路径名)+
        ": "(冒号和一个空格) +
        调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容).
printStackTrace()    -----------------------> 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void, 把信息输出在控制台。
public static void main(String[] args) {
        String s = "2014-11-20";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
                Date d = sdf.parse(s); // 创建了一个ParseException对象,然后抛出去,和catch里面进行匹配
                System.out.println(d);
        } catch (ParseException e) { // ParseException e = new ParseException();
                // getMessage()
                // System.out.println(e.getMessage());
                // Unparseable date: "2014-11-20"

                // toString()
                // System.out.println(e.toString());
                // java.text.ParseException: Unparseable date: "2014-11-20"
                       
                e.printStackTrace();
                //跳转到某个指定的页面(index.html)
        }
        System.out.println("over");
}4、自定义异常
        要想定义一个异常类,该类就必须继承自 Exception 或者 RuntimeException 。
public class MyException extends Exception {
        public MyException() {
        }

        public MyException(String message) {
                super(message);
        }
}

public class MyException extends RuntimeException {
}异常注意事项:
① 子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类;
② 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常;
③ 如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws。
页: [1]
查看完整版本: Java-024异常