面向对象-异常

异常概述

什么是异常(Exception:Java在运行过程当中出现的错误

Throwable 类是 Java 语言中所有错误或异常的超类。

异常:分为运行时异常和编译时异常,我们需要了解的是运行时异常


JVM异常处理方式

JVM是怎么处理异常的

main收到这个异常时,会做两种处理方式

1.自己来去处理

2.自己处理不了,交给调用者jvm来处理

JVM内部会有一个异常处理机制,会把异常的名称,异常信息输出到控制台(创建一个异常对象)

        new ArithmeticException("/by zero");

try_catch处理异常

自己处理异常

1.try...catch...finally

基本格式:

        try {
            可能出现异常的代码
        }catch(异常类型){
            
        }finally {
            处理完异常最后做的处理
        }

Try:用来检测异常

Catch:用来捕获异常

Finally:释放资源

        try {
            int a = 10 / 0;
            System.out.println(a);
        } catch (ArithmeticException a) {
            System.out.println(a);//java.lang.ArithmeticException: / by zero
            System.out.println("除数不能为0");
        }

10/0;会创建一个异常对象

new ArithmeticException("/by zero");赋值给a,int a 接收不了,

此时就把异常对象传给catch当中的参数a,能够接收,就会执行了catch当中的内容,程序也没有终止

只有在try出现问题的时候才会执行catch当中的内容

出现问题的时候catch处理完毕之后,后续的代码继续执行


处理多个异常

try...catch处理多个异常

在try当中可能会出现不同的异常类型,此时可以使用多个catch来进行处理

        try {
            int[] arr = { 10, 20, 30 };
            System.out.println(arr[4]);// ArrayIndexOutOfBoundsException

            int a = 10 / 0;// ArithmeticException

            // 在try当中出现了异常,会立马停止执行了try当中后续的代码
            // 出现异常时会立马跳到catch
            System.out.println("aaa");
            System.out.println("aaa");

        } catch (ArithmeticException a) {
            System.out.println("算数异常");
        } catch (ArrayIndexOutOfBoundsException arr) {
            System.out.println("数组越界异常");
        }catch(Exception e) {
            System.out.println("其他异常");
        }

Exception e不能写在最上面,写在上面会报错,因为下面的永远不会执行到,最常用的

不知道报什么异常的时候,可以写成

        try {
            int[] arr = { 10, 20, 30 };
            
            System.out.println(arr[4]);// ArrayIndexOutOfBoundsException
            int a = 10 / 0;// ArithmeticException
            
        } catch(Exception e) {
            System.out.println("其他异常");
        }

JDK7之后处理多个异常

        try {
            int[] arr = { 10, 20, 30 };
            System.out.println(arr[4]);// ArrayIndexOutOfBoundsException

            int a = 10 / 0;// ArithmeticException

            System.out.println("aaa");
            System.out.println("aaa");
            
            //从jdk7之后可以这样写
        } catch (ArithmeticException  | ArrayIndexOutOfBoundsException e) {
            System.out.println("除数不能为0或者数组越界");
        }

运行时异常与编译时异常

什么是运行时异常?

所有的RuntimeException类及其子类成为运行时异常,在编译时不会报错,在运行过程程序终止运行

什么是编译时异常?

程序员必须显示处理,否则程序就会发生错误无法通过编译

编译时异常发生的情况

FileInputStream fl = new FileInputStream("abc.txt");

运行时异常与编译时异常的区别

运行时异常,程序员犯的错误,需要回来修改代码

编译时异常在编译某个程序的时候,有可能会这样那样的错误,

比如文件找不到,这样的异常就必须在编译时处理

如果不处理就编译不通过

        try {
            FileInputStream fl = new FileInputStream("abc.txt");
        }catch(Exception e) {
            System.out.println("发生异常了");
        }

获取异常信息

常用方法:

1.获取异常信息,返回字符串,参数

        try {
            int a = 10/0;
        }catch(Exception e) {
            System.out.println(e.getMessage());//  / by zero
        }

2.获取异常类名异常信息

        try {
            int a = 10 / 0;
        } catch (Exception e) {//Exception e = new ArithmeticException("/ by zero")
            System.out.println(e.toString());//java.lang.ArithmeticException: / by zero
            System.out.println(e);//java.lang.ArithmeticException: / by zero
        }

3.获取异常类名和异常信息,及异常出现的位置(看异常信息从下往上来去查看)

        try {
            int a = 10 / 0;
        } catch (Exception e) {
            e.printStackTrace();
        }

throw抛出异常

1.抛出运行时异常,不需要处理

class Person {
    private int age;

    public void setAge(int age) {
        if (age > 0 && age <= 150) {
            this.age = age;
        } else {
            // 1.System.out.println("年龄不正确");
            // 2.出现异常,终止程序运行
            throw new RuntimeException("年龄不正确");
        }

    }

}

2.抛出编译时异常

class Person1 {
    private int age;

    public void setAge(int age) throws Exception {//抛出异常
        if (age > 0 && age <= 150) {
            this.age = age;
        } else {
            // 3.编译时异常
            throw new Exception("年龄不正确");
        }

    }

}

抛出了一个编译时异常,必须要得要有人处理

如果不处理,必须继续往上抛,抛给方法调用者

        Person1 per = new Person1();
        per.setAge(-10);

此时由于setAge内部抛出了一个异常,在调用该方法时必须得要处理

1.必须要处理异常

        Person1 per = new Person1();
        try {
            per.setAge(-10);
        } catch (Exception e) {
            e.printStackTrace();
        }

2.继续往上抛出

自己不处理,抛给main方法调用者jvm处理,同样是控制台报出错误

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

        Person1 per = new Person1();
        per.setAge(-10);

    }

throw与throws的区别

throw:

用在方法内,跟的是异常对象名称
只能抛出一个异常对象
表示抛出异常

throws:
用在方法生命后面,跟的是异常类名
可以跟多个异常类名,中间使用逗号隔开
表示抛出异常,由方法调用者来处理


finally

fianlly特点:

被finally控制的语句一定会被执行到

        //只要执行了try,就会执行finally
        try {
            System.out.println(10 / 0);
        } catch (Exception e) {
            System.out.println("错误:除数不能为0");
        } finally {
            System.out.println("执行了finally");
        }

特殊情况:在执行finally之前jvm退出了

        try {
            System.out.println(10 / 0);
        } catch (Exception e) {
            
            System.out.println("错误:除数不能为0");
            //System.exit(0);
            return;//终止当前方法运行,是不能阻止finally
            
        } finally {
            System.out.println("执行了finally");//exit,jvm停止了,不会执行
        }
        System.out.println("end");//不会被执行,方法已经终止了

finally作用:

用来释放资源,在IO操作中经常见到

退出程序:

retrun,终止当前方法运行,并不能阻止finally

exit(0),jvm停止了,finally就不会执行


finally返回值问题

        int x = 10;
        try {
            x = 20;
            System.out.println(1 / 0);
            return x;
        } catch (Exception e) {
            x = 30;
            return x;//return返回的是当时的值
        } finally {//finally一般不做return,只作资源的释放
            x = 40;
        }

    }
        System.out.println(Demo8.test());//30

自定义异常

为什么自定义异常:
系统自带的异常类名称有很多,通过类型就能看出是什么异常,算术异常,空指针异常,数组越界异常

自己也想抛出一个异常,类名是自己定义的,通过类名就能知道是什么类型的异常

自定义运行时的异常:

1.定义一个类继承RuntimeException
2.抛出异常时,抛出自己定义的异常类名

class AgeBoundsException extends RuntimeException{
    
    
}
        throw new AgeBoundsException();

自定义编译时异常:

1.定义一个类继承Exception

class AgeBoundsException extends Exception{
    
    
}

2.抛出异常时,抛出自己定义的异常类名

    public static void main(String[] args) throws AgeBoundsException {
        
        throw new AgeBoundsException();
        
    }

以上两种报异常的方法都是不带参数的

找方法的eclipse的快捷键:Ctrl+O

自定义带参数的异常

1.定义一个类继承RuntimeException或者Exception

在类当中提供一个有参数的构造方法
把参数传给父类构造器

class AgeBoundsException extends Exception{
    
    AgeBoundsException(String message){
        super(message);
    }
}

2.抛出异常时,抛出自己定义的异常类名并且传入对应的参数

    public static void main(String[] args) throws AgeBoundsException {
        
        throw new AgeBoundsException("年龄出问题了");
        
    }

你可能感兴趣的:(面向对象-异常)