java异常详细解读

java异常详细解读

什么是异常?异常是程序中导致程序中断的一段指令流。简单来说,就是你程序运行到某个地方,出错了,会返回一段记录错误的信息。我们可以根据这段错误信息,更好地定位错误的原因,进而对程序进行修改,打补丁。如果程序出现异常,抛出的异常在当前这一级别没有得到处理,异常会不断向上一级抛出,直到异常被处理,或者到达你运行的main方法处,抛给JVM虚拟机,从而引发程序崩溃。
下图中程序可以比较清楚的表达这一过程,不同的是,在这里出现异常的地方在main方法下,程序会直接把异常抛给上一级JVM。而这导致的结果就是,程序直接崩溃,奔溃之后的程序无法运行。在多线程工作环境中,这往往会影响到其他线程的工作。
在这里插入图片描述

异常的体系结构

java有着丰富的多态特征,这一点同样体现在异常这一体系上,为了更好理解,先上图:在这里插入图片描述
异常类和其他java类一样,有着共同的父类Object,而真正让这些类“异常”于其他类的,是父类Throwable,顾名思义,异常类就是用来抛出的。而其中,Error发生代表无法在纯程序层面上进行修复,比如内存溢出。真正考验程序员功底的在Excpetion类,这一部分在理论上可以被程序员修复。
写过java程序的伙伴们会发现,在写一些代码时,编译器会提醒你需要对代码中的某一部分进行异常抛出,并做了强制性要求。而在其他一些可能出现异常的程序,却没有这种强制性的要求。原因在于,前者是受检异常,而后者是非受检异常。前者诸如做一些IO接口连接时,后者诸如算术运算中出现除数为0。详细看图,自行百度浏览官方文件,这里不多篇幅。

抛出异常

记住这句话,原则上,我们要尽可能地为程序可能出现的异常做修补,而并非简单抛出。这也是java设置异常体系的另一个重要原因。语法简要带过

try{
// 有可能发生异常的代码段
 }
catch(异常类型1 对象名1){
 // 异常的处理操作 
 }
catch(异常类型2 对象名2){
// 异常的处理操作
 }
  ...
 finally{
  // 异常的统一出口 
  }

图已经说的很清楚了,对try中可能出现的异常,在catch处进行异常的处理,包括打补丁等操作,finally放的程序是必然运行的,除了强制中断等造成JVM在内存中消失的,更详细可以参考另外这篇文章。

直接上代码例子

public class Demo3 {
    public static void main(String[] args){

        haha();
        System.out.println("程序执行完毕 , 正常结束");
    }

    private static void haha() {
        try {
            Scanner input = new Scanner(System.in);
            System.out.println("请输入一个数字");
            int x = input.nextInt();
            System.out.println("请再输入一个数字");
            int y = input.nextInt();
            System.out.println(x / y);
            System.out.println("处理完毕");
        }catch(InputMismatchException|ArithmeticException e){
            System.out.println("输入有误");
        }
    }
}

当我们输入y=0时,程序在做x/y运算时会抛出ArithmeticException类型的异常。当输入x = "abc"的字符串时,程序在input.nextInt()处抛出InputMismatchException类型的异常。且会在catch出进行异常处理,因此,当运行main时,haha方法会抛出异常,但异常在haha方法内就被处理,不会抛给main方法,JVM不会崩溃,haha方法之后的程序得以正常运行。但这里只是对异常的信息做了简要描述,我们更希望,当程序发生异常时,catch里的代码块能起到些许补救作用。

看另一个例子

public class Test1 {
    public static void main(String[] args) {
        int num = menu();
        System.out.println("你输入的是:"+num);
    }


    public static int menu(){
        System.out.println("请根据提示,选择功能序号:");
        System.out.println("1. 增加XX");
        System.out.println("2. 删除XX");
        System.out.println("3. 修改XX");
        System.out.println("0. 退出");

        Scanner input = new Scanner(System.in);
        int num = -1;
        try{
            num = input.nextInt();
            if(num<0 || num>3){
                //程序有问题 , 输入有误
                System.out.println("功能序号必须是: 0/1/2/3");
                return menu();
            }
            return num;
        }catch(InputMismatchException e){
            //System.out.println("哈哈哈, 程序出错了.");
            //补救
            System.out.println("必须输入数字哦");
            return menu();
        }
    }
}

这个例子中catch就很好地起到这一点,输入值num要求是0/1/2/3中的一个数,当用户输入错误时,我们并不希望程序终止,而更希望让用户重新输入。因此,在catch代码块里返回了一个menu方法,重新进入该方法,让用户重新输入合理的num值。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值