java-异常

2023-12-13 22:06:57
1.public class Test {
2.    //这是一个main方法,是程序的入口:
3.    public static void main(String[] args) {
4.        //实现一个功能:键盘录入两个数,求商:
5.        Scanner sc = new Scanner(System.in);
6.        System.out.println("请录入第一个数:");
7.        int num1 = sc.nextInt();
8.        System.out.println("请录入第二个数:");
9.        int num2 = sc.nextInt();
10.        System.out.println("商:"+num1/num2);
11.
12.    }
13.}

运行结果:

测试过程发现问题:

录入的数据应为int类型,但是录入非int类型数据的时候,出异常:

除数为0的时候:

异常:Exception:在程序的运行过程中,发生了不正常的现象,阻止了程序的运行,我们称之为发生异常。

通过if-else解决异常
1.package com.msb.test01;
2.
3.import java.util.Scanner;
4.
5./**
6. * @Auther: msb-zhaoss
7. */
8.public class Test {
9.    //这是一个main方法,是程序的入口:
10.    public static void main(String[] args) {
11.        //实现一个功能:键盘录入两个数,求商:
12.        Scanner sc = new Scanner(System.in);
13.        System.out.println("请录入第一个数:");
14.        if(sc.hasNextInt()){
15.            int num1 = sc.nextInt();
16.            System.out.println("请录入第二个数:");
17.            if(sc.hasNextInt()){
18.                int num2 = sc.nextInt();
19.                if(num2 == 0){
20.                    System.out.println("对不起,除数不能为0");
21.                }else{
22.                    System.out.println("商:"+num1/num2);
23.                }
24.            }else{
25.                System.out.println("对不起,你录入的不是int类型的数据!");
26.            }
27.        }else{
28.            System.out.println("对不起,你录入的不是int类型的数据!");
29.        }
30.    }
31.}

用if-else堵漏洞的缺点:

(1)代码臃肿,业务代码和处理异常的代码混在一起。

(2)可读性差

(3)程序员需要花费大量的经历来维护这个漏洞

(4)程序员很难堵住所有的漏洞。

try-catch

【1】基于if-else处理异常缺点太多,所以java中专门出了一个异常处理机制:

“异常三连” ?try-catch-finally

【2】异常出现了以后怎么看:

【3】捕获异常:?try-catch

对应代码:

1.public class Test2 {
2.    public static void main(String[] args) {
3.        //实现一个功能:键盘录入两个数,求商:
4.        try{
5.            Scanner sc = new Scanner(System.in);
6.            System.out.println("请录入第一个数:");
7.            int num1 = sc.nextInt();
8.            System.out.println("请录入第二个数:");
9.            int num2 = sc.nextInt();
10.            System.out.println("商:"+num1/num2);
11.        }catch(Exception ex){
12.            System.out.println("对不起,程序出现异常!");
13.        }
14.
15.        System.out.println("----谢谢你使用计算器111");
16.        System.out.println("----谢谢你使用计算器222");
17.        System.out.println("----谢谢你使用计算器333");
18.        System.out.println("----谢谢你使用计算器444");
19.        System.out.println("----谢谢你使用计算器555");
20.        System.out.println("----谢谢你使用计算器666");
21.    }
22.}

原理:

把可能出现异常的代码放入try代码块中,然后将异常封装为对象,被catch后面的()中的那个异常对象接收,接收以后:执行catch后面的{}里面的代码,然后try-catch后面的代码,该怎么执行就怎么执行。

详细说一下:

(1)try中没有异常,catch中代码不执行。

(2)try中有异常,catch进行捕获:

如果catch中异常类型和你出的异常类型匹配的话:走catch中的代码--》进行捕获

如果catch中异常类型和你出的异常类型不匹配的话:不走catch中的代码--》没有捕获成功,程序相当于遇到异常了,中断了,后续代码不执行

注意:

(1)try中如果出现异常,然后用catch捕获成功的话,那么try中后续的代码是不会执行的。

(2)如果catch捕获异常成功,那么try-catch后面的代码该执行还是执行没有影响。

catch中如何处理异常
1.package com.msb.test01;
2.
3.import java.util.Scanner;
4.
5./**
6. * @Auther: msb-zhaoss
7. */
8.public class Test3 {
9.    public static void main(String[] args) {
10.        //实现一个功能:键盘录入两个数,求商:
11.        try{
12.            Scanner sc = new Scanner(System.in);
13.            System.out.println("请录入第一个数:");
14.            int num1 = sc.nextInt();
15.            System.out.println("请录入第二个数:");
16.            int num2 = sc.nextInt();
17.            System.out.println("商:"+num1/num2);
18.        }catch(Exception ex){
19.            //第一种处理:什么都不写,什么都不做
20.
21.            //第二种处理:输出自定义异常信息
22.            //System.out.println("对不起,你的代码有问题!");
23.
24.            //第三种处理:打印异常信息:
25.            /*(1)调用toString方法,显示异常的类名(全限定路径)*/
26.            /*System.out.println(ex);
27.            System.out.println(ex.toString());*/
28.            /*(2)显示异常描述信息对应的字符串,如果没有就显示null
29.            System.out.println(ex.getMessage());*/
30.            /*(3)显示异常的堆栈信息:将异常信息捕获以后,在控制台将异常的效果给我们展示出来,方便我们查看异常*/
31.           /* ex.printStackTrace();*/
32.
33.            //第四种处理:抛出异常:
34.            throw ex;
35.        }
36.
37.        System.out.println("----谢谢你使用计算器111");
38.    }
39.}
try-catch-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);//终止当前的虚拟机执行

1.package com.msb.test01;
2.
3.import java.util.Scanner;
4.
5./**
6. * @Auther: msb-zhaoss
7. */
8.public class Test3 {
9.    public static void main(String[] args) {
10.        //实现一个功能:键盘录入两个数,求商:
11.        try{
12.            Scanner sc = new Scanner(System.in);
13.            System.out.println("请录入第一个数:");
14.            int num1 = sc.nextInt();
15.            System.out.println("请录入第二个数:");
16.            int num2 = sc.nextInt();
17.            System.out.println("商:"+num1/num2);
18.            System.exit(0);//终止当前的虚拟机执行
19.            return;
20.        }catch(ArithmeticException ex){
21.            //throw ex;
22.        }finally {
23.            System.out.println("----谢谢你使用计算器111");
24.        }
25.
26.
27.    }
28.}
多重catch

【1】try中出现异常以后,将异常类型跟catch后面的类型依次比较,按照代码的顺序进行比对,执行第一个与异常类型匹配的catch语句

【2】一旦执行其中一条catch语句之后,后面的catch语句就会被忽略了!

【3】在安排catch语句的顺序的时候,一般会将特殊异常放在前面(并列),一般化的异常放在后面。

先写子类异常,再写父类异常。

【4】在JDK1.7以后,异常新处理方式:可以并列用|符号连接:

1.package com.msb.test01;
2.
3.import java.util.InputMismatchException;
4.import java.util.Scanner;
5.
6./**
7. * @Auther: msb-zhaoss
8. */
9.public class Test4 {
10.    public static void main(String[] args) {
11.        Integer
12.        //实现一个功能:键盘录入两个数,求商:
13.        try{
14.            Scanner sc = new Scanner(System.in);
15.            System.out.println("请录入第一个数:");
16.            int num1 = sc.nextInt();
17.            System.out.println("请录入第二个数:");
18.            int num2 = sc.nextInt();
19.            System.out.println("商:"+num1/num2);
20.        }catch(ArithmeticException ex){
21.            System.out.println("对不起,除数不可以为0");
22.        }catch(InputMismatchException ex){
23.            System.out.println("对不起,你录入的数据不是int类型的数据");
24.        }catch(Exception ex){
25.            System.out.println("对不起,你的程序出现异常");
26.        }finally {
27.            System.out.println("----谢谢你使用计算器111");
28.        }
29.    }
30.}
异常的分类

【1】层次结构:

注意:程序中语法错误,逻辑错误 ?都不属于上面的Error,Exception

【2】运行时异常:

1.public class Test5 {
2.    //这是一个main方法,是程序的入口:
3.    public static void main(String[] args) {
4.        //运行时异常:
5.        int[] arr = {1,2,3};
6.        System.out.println(arr.length);
7.        /*int[] arr2 = null;
8.        System.out.println(arr2.length);*/
9.        System.out.println(arr[10]);
10.    }
11.}

【3】检查异常:

处理方式1:try-catch嵌套try-catch

1.public class Test6 {
2.    //这是一个main方法,是程序的入口:
3.    public static void main(String[] args) {
4.        //检查异常:
5.        try {
6.            try {
7.                Class.forName("com.msb.test01.Test").newInstance();
8.            } catch (InstantiationException e) {
9.                e.printStackTrace();
10.            } catch (IllegalAccessException e) {
11.                e.printStackTrace();
12.            }
13.        } catch (ClassNotFoundException e) {
14.            e.printStackTrace();
15.        }
16.    }
17.}

处理方式2:多重catch

1.public class Test6 {
2.    //这是一个main方法,是程序的入口:
3.    public static void main(String[] args) {
4.        //检查异常:
5.        try {
6.            Class.forName("com.msb.test01.Test").newInstance();
7.        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
8.            e.printStackTrace();
9.        }
10.    }
11.}

处理方式3:throws

1.public class Test6 {
2.    //这是一个main方法,是程序的入口:
3.    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
4.        //检查异常:
5.        Class.forName("com.msb.test01.Test").newInstance();
6.    }
7.}
throw和throws的区别
1.package com.msb.test01;
2.
3.import java.util.Scanner;
4.
5./**
6. * @Auther: msb-zhaoss
7. */
8.public class Test7 {
9.    //这是一个main方法,是程序的入口:
10.    public static void main(String[] args) throws Exception {
11.        //实现一个功能:两个数相除,当除数为0的时候,程序出现异常。
12.        /*try {
13.            devide();
14.        } catch (Exception e) {
15.            e.printStackTrace();
16.        }*/
17.        devide();
18.    }
19.    public static void devide() throws Exception {
20.        Scanner sc = new Scanner(System.in);
21.        System.out.println("请录入第一个数:");
22.        int num1 = sc.nextInt();
23.        System.out.println("请录入第二个数:");
24.        int num2 = sc.nextInt();
25.        if(num2 == 0 ){//除数为0 ,制造异常。
26.            //制造运行时异常:
27.            /*throw new RuntimeException();*/
28.            //制造检查异常:
29.            /*try {
30.                throw new Exception();
31.            } catch (Exception e) {
32.                e.printStackTrace();
33.            }*/
34.            throw new Exception();
35.        }else{
36.            System.out.println("商:"+num1/num2);
37.        }
38.    }
39.}

总结:

throw和throws的区别:

(1)位置不同:

throw:方法内部

throws: 方法的签名处,方法的声明处

(2)内容不同:

throw+异常对象(检查异常,运行时异常)

throws+异常的类型(可以多个类型,用,拼接)

(3)作用不同:

throw:异常出现的源头,制造异常。

throws:在方法的声明处,告诉方法的调用者,这个方法中可能会出现我声明的这些异常。然后调用者对这个异常进行处理:

要么自己处理要么再继续向外抛出异常

1.package com.msb.test02;
2.
3./**
4. * @Auther: msb-zhaoss
5. */
6.public class Student {
7.    private String name;
8.    private int age;
9.    private String sex;
10.
11.    public String getName() {
12.        return name;
13.    }
14.
15.    public void setName(String name) {
16.        this.name = name;
17.    }
18.
19.    public int getAge() {
20.        return age;
21.    }
22.
23.    public void setAge(int age) {
24.        this.age = age;
25.    }
26.
27.    public String getSex() {
28.        return sex;
29.    }
30.
31.    public void setSex(String sex) throws Exception {
32.        if(sex.equals("男")||sex.equals("女")){
33.            this.sex = sex;
34.        }else{//非男非女
35.            //解决办法1:
36.            /*this.sex = "男";*/
37.            //解决办法2:给个友好型提示,但是打印结果为默认的null效果
38.            /*System.out.println("对不起,你的性别错误了");*/
39.            //解决办法3:
40.            //制造运行时异常:
41.            /*throw new RuntimeException("性别不对!");*/
42.            //制造检查异常
43.            /*try {
44.                throw new Exception();
45.            } catch (Exception e) {
46.                e.printStackTrace();
47.            }*/
48.            throw new Exception();
49.        }
50.    }
51.
52.    @Override
53.    public String toString() {
54.        return "Student{" +
55.                "name='" + name + '\'' +
56.                ", age=" + age +
57.                ", sex='" + sex + '\'' +
58.                '}';
59.    }
60.
61.    public Student() {
62.    }
63.
64.    public Student(String name, int age, String sex) {
65.        this.name = name;
66.        this.age = age;
67.        //this.sex = sex;
68.        try {
69.            this.setSex(sex);
70.        } catch (Exception e) {
71.            e.printStackTrace();
72.        }
73.    }
74.}
1.package com.msb.test02;
2.
3./**
4. * @Auther: msb-zhaoss
5. */
6.public class Test {
7.    //这是一个main方法,是程序的入口:
8.    public static void main(String[] args) {
9.        //创建一个Student的对象:
10.        /*Student s = new Student();
11.        s.setName("菲菲");
12.        s.setAge(19);
13.        try {
14.            s.setSex("asdfasdfasdf");
15.        } catch (Exception e) {
16.            e.printStackTrace();
17.        }
18.        System.out.println(s);*/
19.
20.        Student s2 = new Student("娜娜",21,"asdfasdfasdf");
21.        System.out.println(s2);
22.    }
23.}
24.
重载和重写的异常

【1】重载:

1.public class Demo {
2.    public void a() throws Exception{
3.
4.    }
5.    public void a(int age) throws ArithmeticException{
6.
7.    }
8.}

【2】重写:

子类 <= 父类?

自定义异常

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

1.public class MyException extends RuntimeException {
2.    
3.    static final long serialVersionUID = -70348971907L;
4.    
5.    public MyException(){
6.
7.    }
8.    public MyException(String msg){
9.        super(msg);
10.    }
11.}

也可以继承检查异常:

1.public class MyException extends Exception {
2.
3.    static final long serialVersionUID = -70348971907L;
4.
5.    public MyException(){
6.
7.    }
8.    public MyException(String msg){
9.        super(msg);
10.    }
11.}

如果继承的是运行时异常,那么在使用的时候无需额外处理

如果继承的是检查异常,那么使用的时候需要try-catch捕获或者throws向上抛

文章来源:https://blog.csdn.net/weixin_45503872/article/details/134978409
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。