Day19 Java基础-异常(完整)

Day19 Java基础-异常

主要内容

  1. 异常
  2. try-catch-finally
  3. 异常分类
  4. throws和throw
  5. 自定义异常
  6. 面向对象案例:猜丁壳(石头剪子布)

引入异常

注意:异常处理完之后要继续执行后面的代码

面对异常该怎么办?

  • 方法1:由开发者通过if-else来解决异常问题

​ 缺点:代码臃肿,业务代码和异常处理代码放一起

​ 程序员要花很大精力“堵漏洞”

​ 程序员很难堵住所有“漏洞”,对程序员本身要求较高

  • 方法2:开发者不需要通过if-else来解决异常问题,而是Java提供异常处理机制。它将异常处理代码和业务代码分离,使程序更优雅、更好的容错性、高健壮性

​ 程序中预先想好了对付异常的处理办法-------->程序运行------>异常!-------->产生异常对象---------->捕获异常--------->处理异常--------->处理完毕,程序继续运行


异常(Exception)就是在程序的运行过程中所发生的不正常的事件,他会中断正在运行的程序(所需文件找不到、网络连接不通或中断、算术运算错、被0除,数组下标越界、装载一个不存在的类或者对null对象操作、类型转换异常…)

当Java程序出现以上的异常时,就会在所处的方法中产生一个异常对象。这个异常对象包括异常的类型,异常出现时程序的运行状态以及对异常的详细描述


Java的异常处理是通过5个关键字来实现的:try catch finally throw throws

捕获异常
try------------->执行可能产生异常的代码
catch--------->捕获异常
finally---------->无论是否发生异常,代码总能执行
声明异常
throws------------->声明方法可能要抛出的各种异常
抛出异常
throw------------>手动抛出异常

优点:Java已经提供了异常处理机制,发生异常后,会给出异常类型、异常提示信息、异常的位置

缺点:出现异常后,后续语句不执行了;提示信息太专业,可读性差

解决:try-catch-finally 处理异常;throws 抛出异常不处理,调用者处理

public class excep {
    public static void main(String[] args) {
        //try里面的是可能会出错的代码
        try {
            //1.输入总分
            Scanner input = new Scanner(System.in);
            System.out.println("请输入总分");
            int num1 = input.nextInt();

            //2.输入人数
            System.out.println("请输入人数");
            int num2 = input.nextInt();

            //3.计算平均分并输出
            int result = num1 / num2;
            System.out.println("平均分是:"+result);
        }catch (Exception e){
            System.err.println(e.toString());
        }


        System.out.println("3q3q");
        System.out.println("bye");
    }
}

try-catch的执行情况

  • 情况1:try块中代码没有出现异常

    不执行catch代码块,执行catch块后面的代码

  • 情况2:try块中代码出现异常,catch中异常类型匹配(相同或者父类)

    执行catch块代码,执行catch块后边的代码

  • 情况3:try块中代码出现异常,catch中异常类型不匹配

    不执行catch块代码,不执行catch块后边的代码,程序会中断运行

注意:

  1. 出现异常后,Java会生成相应的异常对象,Java系统寻找匹配的catch块,找到后将异常对象付给catch块异常参数
  2. 出现异常后,try块中尚未执行的语句不会执行
  3. 出现异常后并处理后,catch块后面的语句还会执行
public class excep {
    public static void main(String[] args) {
        //try里面的是可能会出错的代码
        try {
            //1.输入总分
            Scanner input = new Scanner(System.in);
            System.out.println("请输入总分");
            int num1 = input.nextInt();

            //2.输入人数
            System.out.println("请输入人数");
            int num2 = input.nextInt();

            //3.计算平均分并输出
            int result = num1 / num2;
            System.out.println("平均分是:"+result);
        }catch (Exception e){  //Exception e = new InputMismatchException(); 多态
            /*情况1:输出自定义信息
            System.out.println("你输入的数字有误");
            */

            /*情况2:输出系统信息
            e.printStackTrace();
             */

            /*
            * 情况3:只输出提示信息
            * System.out.println(e.getMessage());
            */

            /*
            * System.err.println(e.toString());
            * */

            /*
            * 情况4:向上继续抛(抛不抛到后面讲)(分层开发,底层向上抛)
            */
            throw e;
        }
        System.out.println("3q3q");
        System.out.println("bye");
    }
}
异常类型说明
Exception异常层次结构的根类
ArithmeticException算术错误情形,如以零作除数
ArrayIndexOutOfBoundsException数组下标越界
NullPointerException尝试访问null对象成员
ClassNotFoundException不能接在所需的类
InputMismatchException欲得到数据类型与实际输入类型不匹配
IllegalArgumentException方法接收到非法参数
ClassCastException对象强制类型转换出错
NumberFormatException数字格式转换异常,如把“ac”转换成数字

问题1:哪些情况下的catch后面的语句不执行

​ 情况1:throw e;

​ 情况2:catch的异常类型不匹配

​ 情况3:遇到了return语句

问题2:不管成功失败,某些语句必须执行

​ 加finally语句

问题3:finally语句的作用,哪些语句应该放到finally中

​ conn.close();数据库、fis.close() fos.close() IO流

​ socket.close()

问题4:执行的顺序

​ System.out.println(“平均分是:”+result);

​ System.out.println(“3q3q”);

​ return;

问题5:有没有例外的情况?

​ System.exit(0); 退出虚拟机

​ return:结束当前方法

多重catch处理异常

import javax.naming.AuthenticationException;
import java.util.InputMismatchException;
import java.util.Scanner;

public class excep {
    public static void main(String[] args) {
        //try里面的是可能会出错的代码
        try {
            //1.输入总分
            Scanner input = new Scanner(System.in);
            System.out.println("请输入总分");
            int num1 = input.nextInt();

            //2.输入人数
            System.out.println("请输入人数");
            int num2 = input.nextInt();

            //3.计算平均分并输出
            int result = num1 / num2;
            System.out.println("平均分是:"+result);
            return;
        }catch (ArithmeticException e){
            System.out.println("除数不能为0");
        }

        catch (InputMismatchException e){
            System.out.println("必须为数字");
        }

        catch (Exception e){
            System.out.println("其他异常");
        }

        finally {
            System.out.println("3q3q");
        }
        System.out.println("bye");
    }
}
  • 当引发异常时,会按照顺序来查看每个catch语句,并执行第一个与异常匹配的catch语句

  • 执行其中一条catch语句后,其后catch语句将被忽略

  • 在安排catch语句的顺序时,首先应该捕获最特殊的异常,然后再逐渐一般化,即先子类后父类

  • 了解JDK7的异常处理方式

    catch(ArithmeticException  | InputMismatchException e){}
    

异常体系结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6MjikOQe-1634321276350)(C:\Users\50092\Desktop\JAVA\截图\000000001.jpeg)]

Error

  • Error类层次描述了Java运行时系统内部错误和资源耗尽错误,一般指与JVM或动态加载等相关问题,如虚拟机错误,动态链接失败,系统崩溃等。
  • 这类错误我们无法控制的,同时也是非常罕见的错误。所以在编程中,不去处理这类错误。我们不需要管理Error

Exception

  • 所有异常类的父类,其子类对应了各种各样可能出现的异常事件

Exception分类

  • 运行时异常 Runtime Exception(unchecked Exception)

    可不必对其处理,系统自动检测处理

    一类特殊的异常,如被0除、数组下标超范围等,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大

  • 检查异常 Checked Exception

    必须捕获进行处理,否则会出现编译错误

    注意:只有Java提供了Checked异常,体现了Java的严谨性,提高了Java的健壮性。同时也是一个备受争议的问题

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Locale;

public class exp2 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //int[] arr = new int[10];
        //System.out.println(arr[11]);  //ArrayIndexOutOfBoundsException:数组下标越界
        System.out.println("=========");

       //String str = "sad";
       //str = null;
        // System.out.println(str.toUpperCase());       //NullPointerException 空指针

        System.out.println(10/0);  //ArithmeticException:算术异常
        //以上都属于运行时异常



        //检查异常  checked exception
        try {
            Class.forName("java.lang.String").newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        Class.forName("java.lang.String").newInstance();  //继续向上抛,让调用者处理


        try {
            new FileOutputStream("c:/abc.txt");//IO流   处理两种方法
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


    }
}

异常处理:throws,throw

手动抛出异常throw

  • Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要手动创建并抛出
  • 在捕获一个异常前,必须有一段代码先生成异常对象并把它抛出。这个过程我们可以手动做,也可以由JRE来实现,但是他们调用的都是throw子句
  • 注意抛出运行时异常和Checked异常的区别

​ 抛出Checked异常,该throw语句要目处于try块中,要么方法签名中使用throws抛出

  • 抛出运行时异常,没有以上要求

声明异常throws

  • 当Checked Exception产生时,不一定立刻处理它,可以再把异常Throws出去
  • 如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开
  • 子类声明的异常范围不能超过父类声明范围:父类没有声明异常,子类也不能;不可抛出原有方法抛出异常类的父类或上层类
import java.util.Scanner;

/*
* throws和throw的区别:
* 1.作用:
*   throws声明,说明方法里面有异常
*   throw产生异常的地方,并往上抛
*
* 2.位置
*   throws在方法签名里面
*   throw在方法体里面
*
* 3.数量
*   throws后面跟的是一个一个类
*   throw 是new一个对象,也只能一个
* */


public class clacavg {
    public static void main(String[] args)  {
        try {
            clacavg();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //第二种办法:clacavg();   向上抛throws Exception
    }

    public static void clacavg() throws Exception {
        //1.输入总分
        Scanner input = new Scanner(System.in);
        System.out.println("请输入总分:");
        int num1 = input.nextInt();

        //2.输入人数
        System.out.println("输入人数:");
        int num2 = input.nextInt();

        //如果人数是负数,产生一个异常并抛出
        if(num2<0){
            //throw new RuntimeException("输入人数不能小于0"); 抛出的运行异常不需要抛出
            throw new Exception("输入人数不能小于0"+ num2);//自己检查异常必须抛出
        }

        //3.计算平均数并输出
        int result = num1 / num2;
        System.out.println("平均分是:"+ result);
        
        System.out.println("3q3q");
        System.out.println("886");
    }
}
public class Person {
    private String name;
    private int age;

    //无参构造方法
    public Person() {
    }

    //有参构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) throws Exception {
        if(age<0 || age>130){
            //System.out.println("年龄输入错误");
            //return;

            //throw new RuntimeException("年龄输入错误");//遇到throw程序会自动结束,比如这句完了就没了

            throw new Exception("年龄输入错误");
        }
        this.age = age;
    }

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

    public static void main(String[] args){
        Person person = new Person();
        try {
            person.setAge(221);
        } catch (Exception e) {
            e.printStackTrace();
        }//用了try-catch,后面的代码继续执行,向上抛throws后面的代码不执行
        person.setName("张三");
        System.out.println(person.toString());
    }
}

自定义异常

//自定义异常:人数不是负数的异常
//继承 分为运行时异常(RuntimeException)和异常(Exception)
public class CountMinusException extends Exception{
    public CountMinusException() {
        super();
    }

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

异常链

实战再讲

rintStackTrace();
}//用了try-catch,后面的代码继续执行,向上抛throws后面的代码不执行
person.setName(“张三”);
System.out.println(person.toString());
}
}


## 自定义异常

```java
//自定义异常:人数不是负数的异常
//继承 分为运行时异常(RuntimeException)和异常(Exception)
public class CountMinusException extends Exception{
    public CountMinusException() {
        super();
    }

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

异常链

实战再讲

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值