JAVA学习之异常

异常

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

if - else 处理异常

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

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

try - catch 异常处理机制
try - catch - finally

public class Test1 {
    public static void main(String[] args) {
        try{
            Scanner sc = new Scanner(System.in);
            int num1 = sc.nextInt();
            int num2 = sc.nextInt();
            int sol = num1 / num2;
        }catch (Exception e){
            System.out.println("程序出现异常");
        }
        System.out.println("------ thanks");
    }
}

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

详细说下:
1.try中没有异常,cacthh中代码不执行
2.try中有异常,catch进行捕获
如果catch中的异常类型,和代码出的异常类型匹配的话,catch可以捕获
如果catch中的异常类型,和代码出的异常类型不匹配,catch无法捕获,程序相当于遇到异常,代码运行中断。

注意:
1.try中如果出现异常,catch捕获成功,那么try中后续的代码是不会执行的
2.如果catch捕获异常成功,那么try - catch后面的代码该执行还是执行,没有影响

catch中处理异常的方式

public class Test1 {
    public static void main(String[] args) {
        try{
            Scanner sc = new Scanner(System.in);
            int num1 = sc.nextInt();
            int num2 = sc.nextInt();
            int sol = num1 / num2;
        }catch (Exception e){
            // 处理方式1 不进行处理

            // 处理方式2
            System.out.println("代码有问题");

            // 处理方式3 打印异常信息
            /*  1.调用toString 方法 显示异常的类名 (全限定路径)*/
            System.out.println(e.toString());
            /*  2. getMessage 显示异常描述信息对应的字符串,如果没有显示null*/
            System.out.println(e.getMessage());
            /*  3. printStackTrace() 显示异常的堆栈信息*/
            e.printStackTrace();

            // 处理方式4 抛出异常
            throw e;
        }
        System.out.println("------ thanks");
    }
}

异常_finally
【1】在什么情况下,try-catch后面的代码不执行?
1.throw抛出异常的情况
2.catch中没有正常的进行异常捕获
3.在try中遇到return

【2】怎么样才可以将try-catch 后面代码必须执行?
只要将必须执行的代码放入 finally,那么这个代码无论如何一定执行

【3】return和finally执行顺序?
先执行finally,最后执行return

【4】System.exit(0) 可以让finally中的代码不执行 , 即终止当前虚拟机的执行

public class Test1 {
    public static void main(String[] args) {
        try{
            Scanner sc = new Scanner(System.in);
            int num1 = sc.nextInt();
            int num2 = sc.nextInt();
            int sol = num1 / num2;
        }catch (Exception e){
            throw e;
        }finally {
            System.out.println("------ thanks");
        }
    }
}

异常_多重catch
【1】try中出现异常后,将异常类型与catch后面的类型依次比较,然后按照代码顺序,进行比对,执行第一个与异常类型相匹配的catch语句
【2】一旦执行其中一个catch ,其他的catch就被忽略了
【3】在安排catch语句的顺序时,一般会将特殊异常放在前面(并列),一般话的异常放在后面 即 先写子类异常,后写父类异常
【4】JDK1.7以后新的异常处理方式。
在这里插入图片描述
异常的分类
【1】层次结构
在这里插入图片描述

【3】运行时异常
NullPointerException
ArrayIndexOutOfBoundsException

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(arr[10]);
        System.out.println(arr2.length);
    }
}

【4】检查异常
方式一: 多重catch

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

方式二:throws

public class Test6 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        // 检查异常
            Class.forName("com.jf.test01.Test").newInstance();
    }
}

throw 和 throws的区别

总结:
1.位置不同
throw:在方法内部
throws:在方法的签名处,方法的声明处
2.内容不同
throw + 异常对象(检查时异常,运行时异常)
throws + 异常类型 (可以多个异常类型,用逗号拼接)
3.作用不同
throw:异常出现的源头,制造异常
throws:在方法的声明出,告诉方法的调用者,这个方法中可能会出现我声明的这些异常,然后调用者对这个异常进行处理:1.自己处理 2.继续向外抛出异常

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + 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("男".equals(sex) || "女".equals(sex)){
            this.sex = sex;
        }else{
            // 方式一: 制造运行时异常
            /*throw new RuntimeException("input mistake");*/
            //  方式二: 制造检查时异常
            /*throw new Exception();*/
            // 方式三: throws 不处理 抛给调用者处理
            throw new Exception();
            // 方式四: throw 检查时异常在此方法中处理
            /*try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }*/
        }
    }

    public Student() {
    }

    public Student(String name, int age, String sex) throws Exception {
        this.name = name;
        this.age = age;
        /*this.sex = sex;*/
        setSex(sex);
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Student s1 = new Student();
        s1.setName("Alice");
        s1.setAge(30);
        s1.setSex("女");
        System.out.println(s1);
    }
}

异常_重载和重写异常的区别

【1】重载: 无关与异常

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

【2】重写:
在这里插入图片描述
在这里插入图片描述
throws 抛出异常
子类 异常类型 <= 父类 异常类型

自定义异常
自定义的异常继承运行时异常

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

    public MyException(){}

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

也可以继承检查异常

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

    public MyException(){}

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值