Java异常处理

【一】异常_异常的案例引入

代码:

public class Test {
    public static void main(String[] args) {
        //实现一个功能:键盘录入两个数,求商;
        Scanner sc=new Scanner(System.in);
        System.out.println("请录入第一个数:");
        int numl=sc.nextInt();
        System.out.println("请录入第二个数:");
        int num2=sc.nextInt();
        System.out.println("商:"+numl/num2);
    }
}

结果:
在这里插入图片描述
测试过程中发现问题:
录入的数据应为int类型,但是录入非int类型数据的时候,出异常。
在这里插入图片描述
除数为0的时候
在这里插入图片描述
异常: Exception:在程序的运行过程中,发生了不正常的现象,阻止了程序的运行,我们称之为发生异常

【二】异常_用if_else处理异常

public class Test {
    public static void main(String[] args) {
        //实现一个功能:键盘录入两个数,求商;
        Scanner sc=new Scanner(System.in);
        System.out.println("请录入第一个数:");
        if(sc.hasNextInt()){
            int numl=sc.nextInt();
            System.out.println("请录入第二个数:");
            if(sc.hasNextInt()){
                int num2=sc.nextInt();
                if(num2==0){
                    System.out.println("对不起除数不能为0");
                }else{
                    System.out.println("商:"+numl/num2);
                }
            }
        }else{
            System.out.println("对不起,你录入的不是int类型的数!");
        }
    }
}

用if_else堵漏洞的缺点:
(1)代码臃肿,业务代码和处理异常的代码混在一起。
(2)可读性差。
(3)程序员需要花费大量的精力来维护这个漏洞。
(4)程序员很难堵住所有的漏洞。

【三】异常_try-catch捕获异常

【1】基于if_else处理异常缺点太多,所有Java中专门出了一个异常处理机制:
”异常三连“try-catch-finally
【2】异常出现了以后怎样看:
在这里插入图片描述
【3】捕获异常:try-catch

public class Test2 {
    public static void main(String[] args) {
        //实现一个功能:键盘录入两个数,求商:
        try{
            Scanner sc=new Scanner(System.in);
            System.out.println("请录入第一个数:");
            int numl=sc.nextInt();
            System.out.println("请录入第二个数:");
            int num2=sc.nextInt();
            System.out.println("商:"+numl/num2);
        }catch (Exception ex){
            System.out.println("对不起你的程序异常了!");
        }
        System.out.println("谢谢使用计算器!");
    }
}

原理:
把可能出现异常的代码放入try代码块中,然后将异常封装为对象,被catch 后面的( )中的那个异常对象接收,接受以后:执行catch后面的{ }里面的代码,然后try-catch后面的代码,该怎么执行就怎么执行。
详细说一下:
(1)try中没有异常,catch中代码不执行。
(2)try中有异常,catch进行捕获。
如果catch中异常类型和你出的异常类型匹配的话:走catch中的代码–》进行捕获
如果catch中异常类型和你出的异常类型不匹配的话:不走catch中的代码–》没有捕获成功,程序相当于遇到异常了,中断了,后续代码不执行,

注意:
(1)try中如果出现异常,然后用catch捕获成功的话,那么try中后续的代码时不会执行的
(2)如果catch捕获异常成功,那么try-catch后面的代码该执行还是执行没有影响。
catch处理异常的四种方式:

public class Test3 {
        public static void main(String[] args) {
            //实现一个功能:键盘录入两个数,求商:
            try{
                Scanner sc=new Scanner(System.in);
                System.out.println("请录入第一个数:");
                int numl=sc.nextInt();
                System.out.println("请录入第二个数:");
                int num2=sc.nextInt();
                System.out.println("商:"+numl/num2);
            }catch (Exception ex){
                //第一种处理:什么都不写,什么都不做

                //第二种处理:输出自定义异常信息
//                System.out.println("对不起你的程序异常了!");

                //第三种处理:打印异常信息:
                /*
                (1)调用toString方法,显示异常的类名(全限定路径)
                 */
//                System.out.println(ex.toString());
                /*
                (2)显示异常描述信息对应的字符串,如果没有就显示null
                 */
//                System.out.println(ex.getMessage());
                /*
                (3)显示异常的堆栈信息:将异常信息捕获以后,在控制台将异常的效果给我们展示出来,方便我们查看异常
                 */
//                ex.printStackTrace();
                //第四种处理:抛出异常
                throw ex;
            }
            System.out.println("谢谢使用计算器!");
        }
}

【四】异常_finally

【1】在什么情况下,try_catch后面的代码不执行?
(1)throw抛出异常的情况
(2)catch中没有正常的进行异常捕获
(3)在try中遇到return
【2】怎么样才可以将try_catch后面的代码 必须执行?
只要将必须执行的代码放入finally中,那么这个代码无论如何一定执行。
【3】return和finally执行顺序?
先执行finally,最后执行return
【4】什么代码会放在finally中呐?
关闭数据库资源,关闭IO流资源,关闭socket资源。
【5】有一句代码很厉害,它可以让finally中代码不执行!

System.exit(0);//终止当前的虚拟机执行

代码:

public class Test3 {
        public static void main(String[] args) {
            //实现一个功能:键盘录入两个数,求商:
            try{
                Scanner sc=new Scanner(System.in);
                System.out.println("请录入第一个数:");
                int numl=sc.nextInt();
                System.out.println("请录入第二个数:");
                int num2=sc.nextInt();
                System.out.println("商:"+numl/num2);

            }catch (Exception ex){
                //throw ex;
                System.exit(0);//终止当前的虚拟机执行
                return ;
            }finally {
                System.out.println("谢谢使用计算器!");
            }
        }
}

【五】异常_多重catch

【1】try中出现异常以后,将异常类型跟catch后面的类型依次比较,按照代码的顺序进行比对,执行第一个与异常类类型匹配的catch比较。
【2】一旦执行其中一条catch语句之后,后面的catch语句就会被忽略。
【3】在安排catch语句的顺序的时候,一般会将特殊异常放在前面(并列),一般化的异常放在后面。
先写子类异常,再写父类异常。
【4】在JDK1.7之后,异常新处理方式:可以并列用 | 符号连接:
Ctrl+B 进入源码查看
在这里插入图片描述
代码:

public class Test4 {
        public static void main(String[] args) {
            //实现一个功能:键盘录入两个数,求商:
            try{
                Scanner sc=new Scanner(System.in);
                System.out.println("请录入第一个数:");
                int numl=sc.nextInt();
                System.out.println("请录入第二个数:");
                int num2=sc.nextInt();
                System.out.println("商:"+numl/num2);

            }catch (InputMismatchException ex){
                System.out.println("对不起,你录入的数据不是int类型的数据!");
            }catch(ArithmeticException ex){
                System.out.println("对不起,除数不可以为0");
            }catch(Exception ex){
                System.out.println("对不起,你的程序出现异常!");
            }
            finally {
                System.out.println("谢谢使用计算器!");
            }
        }
}

【六】异常_异常的分类,层次结构

【1】层次结构
在这里插入图片描述
注意:程序中语法错误,逻辑错误 都不属于Error,Exception
【2】运行时异常

public class Test5 {
    public static void main(String[] args) {
        //运行时异常:
        int []arr={1,2,3};
        System.out.println(arr.length);
        /*int []arr2=null;
        System.out.println(arr2.length);*/
    }
}

【3】检查异常 Alt+Enter
(1)处理方式1:try-catch嵌套try-catch

public class Test6 {
    public static void main(String[] args) {
        //检查异常
        try {
            try {
                Class.forName("aaaaaa").newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

(2)处理方式2:多重catch

public class Test6 {
    public static void main(String[] args) {
        //检查异常
        try {
            Class.forName("aaaaaa").newInstance();
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

(3)处理方式3:throws

public class Test6 {
    public static void main(String[] args) throws ClassNotFoundException {
        //检查异常
        
            Class.forName("aaaaaa");
    }
}

【七】异常_throw和throws的区别

代码:

public class Test7 {
    public static void main(String[] args) throws Exception {
        //实现一个功能:两个数相除,当除数为0的时候,程序出现异常
        devide();
    }
    public static void devide() throws Exception {
        Scanner sc=new Scanner(System.in);
        System.out.println("请录入第一个数:");
        int numl=sc.nextInt();
        System.out.println("请录入第二个数:");
        int num2=sc.nextInt();
        if(num2==0){  //除数为0,制造异常
            //制造运行时异常
//            throw new RuntimeException();
            //制造检查异常
            /*try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }*/
            throw new Exception();     
        }else{
            System.out.println("商:"+numl/num2);
        }
    }
}

总结:
throw和 throws的区别:
(1)位置不同:
throw:方法内部
throws:方法的签名处,方法的声明处

(2)内容不同:
throw+异常对象(检查异常,运行时异常)
throws+异常的类型(可以多个类型,用,连接)

(3)作用不同:
throw:异常出现的源头,制造异常
throws:在方法的声明处,告诉方法的调用者,这个方法中可能会出现我声明的这些异常
,然后调用者对这个异常进行处理:要么自己处理要么再继续向外抛出异常。
代码:

public class Student {
    private String name;
    private int age;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) throws Exception {
        if(sex.equals("男")||sex.equals("女")){
            this.sex = sex;
        }else{//非男非女
            //解决方法1:
            /*this.sex="男";*/
            //解决办法2:给个友好性提示,但是打印结果为默认的null效果
            System.out.println("对不起,你的性别错误了!");
            //解决办法3:
            //制造运行时异常
            //throw new RuntimeException("性别不对!");
            //制造检查时异常:
            /*try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }*/
            throw new Exception();
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }

    public Student() {
    }

    public Student(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        try {
            this.setSex(sex);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
public class Test {
            public static void main(String[] args) throws Exception {
                //创建一个Student对象
                Student s=new Student();
                s.setName("平平");
                s.setAge(18);
        s.setSex("女");
        System.out.println(s);

        Student s2=new Student("朋友",18,"女");
        System.out.println(s2);
    }
}

【八】异常_重载和重写异常的区别

【1】重载:

public class Demo {
    public void A() throws Exception{
        
    }
    public void A(int age) throws ArithmeticException{
        
    }
}

【2】重写:
在这里插入图片描述
在这里插入图片描述
子类<=父类

【九】异常_自定义异常

代码:

public class MyException extends RuntimeException{
    static final long serialVersionUID = -70348971L;

    public MyException() {
    }

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

自定义的异常可以继承:运行时异常

public class MyException extends RuntimeException{
    static final long serialVersionUID = -70348971L;

    public MyException() {
    }

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

也可以继承检查异常:

public class MyException extends Exception{
    static final long serialVersionUID = -70348971L;

    public MyException() {
    }

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

如果继承的是运行时异常,那么在使用的时候无需额外处理
如果继承的时检查异常,那么使用的时候需要try_catch捕获或者throws向上抛

引用:马士兵教育珊珊老师、Java开发手册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值