异常

作者: Anwfly | 来源:发表于2020-08-02 21:22 被阅读0次

    一、异常

    1. 什么是异常

    异常是程序在运行期发生的不正常的事件,它会打断指令的正常执行流程。

    2.异常的由来

    通过java的类的形式对现实事物中问题的描述,并封住成了对象。其实就是java对不正常情况描述后的对象体现。

    3.常见的异常类

    算术异常类 ArithmeticExecption
    空指针异常类 NullPointerException
    类型强制转换异常 ClassCastException
    数组负下标异常 NegativeArrayException
    数组下标越界异常 ArrayIndexOutOfBoundsException
    违背安全原则异常 SecturityException
    文件已结束异常 EOFException
    文件未找到异常 FileNotFoundException
    字符串转换为数字异常 NumberFormatException
    操作数据库异常 SQLException
    输入输出异常 IOException
    方法未找到异常 NoSuchMethodException
    抽象方法错误,当应用试图调用抽象方法时抛出 java.lang.AbstractMethodError

    二、异常的分类

    1.异常的超类和相关子类

    throwable.jpg

    ①Throwable是所有异常的根,java.lang.Throwable
    ②Error是错误,java.lang.Error
    ③Exception是异常,java.lang.Exception

    2. Exception和RuntimeException

    Java中的异常被分为两大类:编译时异常和运行时异常。所有的RuntimeException类及其子类的实例被称为运行时异常,其他的异常就是编译时异常。

    3.异常例子:1除数为0, 2 数组访问越界

    除数为0:
    JVM发现运算是已经违反了数学运算规则,java将这种常见的问题进行描述,并封装成了对象叫ArithmeticException。当除0运算发生后,jvm将该问题打包成了一个异常对象.并将对象抛给调用者main函数,new ArithmeticException("/by zero");

    public static void main(String[] args) throws ArithmeticException {
        //分子
        int a=3;
        // 分母
        int b=0;
        int result = a/b;
        System.out.println(result);
    }
    

    运行结果:

    P2-01.png

    数组访问越界:
    访问的数组下标不存在。

    public static void main(String[] args) {
        int [] a={1,2,3};
        System.out.println(a[4]);
    }
    

    运行结果:

    P2-04.png

    三、异常的处理

    1. JVM的默认处理方法

    代码抛出异常JVM会帮我们创建对象,抛出异常类型。

    案例:

    public static void main(String[] args) throws NumberFormatException {
        //不是纯数字字符串    
        String b = "hello";
        //数字转换异常
        System.out.println(Integer.parseInt(b));        
    }
    

    运行结果:

    P2-02.png

    2.一个异常的情况

    使用try…catch…finally处理异常。

    基本格式:try是检测异常,catch是用来捕获异常的,finally是用来结束资源的。世界上最真情的相依,是你在try我在catch,无论你发神马脾气,我都默默接受,静静处理采用RuntimeException。

    案例

    public static void main(String[] args) {
            try {
                int [] a={1,2,3};
                System.out.println(a[4]);
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
            }finally {
                System.out.println("一定会执行的逻辑");
            }
    }
    

    3.多个异常的情况分情况考虑

    1. 每一个写一个try...catch
    
    2. 写一个try,多个catch
    ​          try{
    
    ​              ...
    
    ​          }catch(异常类名 变量名) {
    
    ​              ...
    
    ​          }catch(异常类名 变量名) {
    
    ​              ...
    ​          }
                ...
    
    

    案例:

    public static void main(String[] args) {
        try {
           int [] a={1,2,3};//定义一个数组
           int[] b=null;//定义一个null数组对象
            //打印结果
           System.out.println(a[4]);//报数组下标越界
           System.out.println(b.length);//报空指针异常    
        } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
        } catch (NullPointerException e) {
                e.printStackTrace();
        } 
    }
    

    *注意:
    一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配,一旦有匹配的,就执行catch里面的处理,然后结束了try...catch继续执行后面的语句。

    4. 父子类异常注处理意事项

    public class Father {
        public void xxx()  {
            
        }
    }
    
    public class Child extends Father {
        //子类抛出异常只能是父类抛出相同异常或父类抛出的异常子类
        @Override
        public void xxx() throws Exception {
            super.xxx();
        }
    }
    
    1. 能明确的尽量明确,不要用大的来处理。
    2. 平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。
    3. 父类的xxx方法没有抛出异常,子类抛出异常只能是父类抛出相同异常或父类抛出的异常子类。

    四、编译时异常和运行时异常的区别

    编译时异常:
    Java程序必须显示处理,否则程序就会发生错误,无法通过编译。
    运行时异常:
    无需显示处理,也可以和编译时异常一样处理。

    五、超类Throwable中的相关方法

    //获取异常信息,返回字符串
    getMessage()
    
    //获取异常类名和异常信息,返回字符串
    toString()
    
    //获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。获取异常所有信息
    printStackTrace()
    
    //通常用该方法将异常内容保存在日志文件中,以便查阅
    //参数:打印流
    printStackTrace(PrintStream s)
    

    六、java提供的其他异常处理方案

    1. throws的特点和注意事项

    有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。或者说,我处理不了,我就不处理了。 为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。

    格式:

    ​ throws 异常类名 ,这个格式必须跟在方法的括号后面。

    *注意:

    ​ 尽量不要在main方法上抛出异常。

    ​ 但是我讲课为了方便我就这样做了。

    小结:

    ​ 编译期异常抛出,将来调用者必须处理。

    ​ 运行期异常抛出,将来调用可以不用处理。

    2. throw的特点和注意事项

    如果出现了异常情况,我们可以把该异常抛出,这个时候的抛出的应该是异常的对象。

    3. throws和throw的区别

    throws:

    1.  用在方法声明后面,跟的是异常类名
    ​2.  可以跟多个异常类名,用逗号隔开
    3.  表示抛出异常,由该方法的调用者来处理
    4.  throws表示出现异常的一种可能性,并不一定会发生这些异常
    

    throw:

    1.  用在方法体内,跟的是异常对象名
    2.  只能抛出一个异常对象名
    3.  表示抛出异常,由方法体内的语句处理
    4.  throw则是抛出了异常,执行throw则一定抛出了某种异常
    

    4. finally的特点作用

    finally的特点:

    1.被finally控制的语句体一定会执行

    1. 特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))

    finally的作用:

    1. 用于释放资源,在IO流操作和数据库操作中会见到

    5.自定义异常方案

    ​ 考试成绩必须在0-100之间:很明显java没有对应的异常,需要我们自己来做一个异常。

    自定义异常:

    继承自Exception,或者继承自RuntimeException。

    案例

    /**
     * 自定义异常
     */
    public class MyException extends Exception {
        //无参构造
        public MyException() {
        }
        //有参构造
        public MyException(String message) {
            super(message);
        }
    }
    
    public static void main(String[] args) throws MyException  {
        //考试成绩必须在0-100之间
        int score =110;
        if (score>=0&&score<=100){
              System.out.println(score);
        }else{
              throw new MyException("考试成绩必须在0-100之间");
        }
    }
    

    运行结果:

    P2-03.png

    七、异常注意事项

    1.子类重写父类方法时有什么特点

    子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)

    2.父类抛出多个异常会有什么情况

    如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常

    3. 如果被重写的方法没有抛出异常那么子类有什么变化

    1. 能明确的尽量明确,不要用大的来处理。
    2. 平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。

    相关文章

      网友评论

          本文标题:异常

          本文链接:https://www.haomeiwen.com/subject/lalmrktx.html