分类在日常的编程中,我们的程序难免会出现各种各样的问题,比如格式错误、标点错误、输入不匹配、数组越界等等,有的是语法错误,有的是不正常。理解异常观察下面的写法,我们可以看到,在Java中,不同的异常是通过对应的类来描述的。算术异常:数组越界:空指针:异常的本质我们从这张图来分析一下:我们说的异常涵盖了很多类,包括Throwable类、Exception、RuntimeException等等。Throwable:属于异常系统的顶级类,派生出两个子类:Error和Exception;Error:属于Java虚拟机无法处理的严重错误。如:JVM内部错误、资源耗尽等;Exception:这就是我们常说的异常,程序员可以处理的异常,默认是编译时异常。异常的分类异常是根据程序的执行时间来分类的。主要有编译时异常和运行时异常两类。另外,还有一个自定义的异常,在最后会解释。1.编译时异常程序编译时出现的异常也称为检查异常;由于在编译过程中出现了异常,如果程序要执行,就必须想办法处理这样的异常。2.运行时异常程序运行过程中发生的异常也称为非检查异常;所有运行时异常的父类都是RuntimeException异常的处理。我们一直在讲异常的发生,那么如何处理这些异常呢??有两种主要类型的异常处理。需要捕获异常,也可以主动抛出异常。下面仔细分析一下:处理方式:1.LBLY预防御型:在运行前做好充分准备,一旦某个步骤出现异常需要处理或终止。2、EAFP事后错误识别类型:try-catch,先完成所有流程,最后报告发生的异常,再根据情况处理或终止;这种写法的好处是正常流程和异常处理分开了,阅读方便,代码清晰。异常抛出当我们知道自己编写的程序的某个部分容易出现异常时,我们可以在执行点主动抛出异常,这样便于观察和发现问题。在Java中,可以使用throw关键字将异常对象抛给调用者;throw必须写在方法体内;抛出的对象必须是Exception或者Exception的子类对象;如果只抛出Exception,则默认勾选Abnormal;如果抛出RunTimeException或者RunTimeException的子类,可以不处理直接交给JVM处理,但是一旦交给JVM处理,程序就会终止;如果抛出编译时异常,用户必须处理,否则无法编译;一旦抛出异常,后面的代码将不会执行;当需要抛出检查异常时:你不能只抛出它而不处理它;处理方法:1.try-catch-自己处理;2.throws语句——交给JVM;exception语句当方法中抛出编译时异常,而用户不想处理该异常时,可以使用throws将异常抛给方法的调用者处理。即当前方法不处理异常,提醒方法的调用者处理异常。异常捕获使用try-catch:将可能出问题的代码存放在try中;可能的异常被捕获;观察下面例子的执行:捕获和抛出异常是一样的:捕获和抛出异常是不同的:如何选择合适的处理方式:对于比较严重的问题(比如支付相关的场景),程序应该直接crash到防止更严重的后果;对于不太严重的问题,可以记录错误日志,并通过监控报警程序及时发送通知;对于可能恢复的问题(网络相关场景),可以尝试重试;在我们当前的代码中,我们采用简化的第二种方法。我们记录的错误日志就是异常的方法调用信息,可以非常快速的让我们找到异常的位置;finally处理在写程序的时候,在一些特定的情况下,不管程序是否有异常,都需要执行,比如程序中打开的资源:网络连接,数据库连接,IO流等。当程序正常退出或异常退出,必须回收资源。另外,由于异常会导致程序跳转,有些语句可能不会执行,finally就是用来解决这个问题的。使用方法:也可以在try后加上参数:此时资源会自动关闭。问题:如果finally有return,返回给谁?异常的意义是什么?1、准确定位异常情况2、不交给JVM处理,即使发生异常,我们仍然可以执行后续代码;有时Java自定义异常类中内置的异常类型不能满足项目的实际需要。这时候就需要我们自己定义合适的了。异常类。自定义异常非常重要。如果项目很大,只通过打印检查效率很低。自定义异常通常继承自Exception或RuntimeException;继承自Exception的异常默认是检查异常;继承自RuntimeException的异常默认为未检查异常;如何定制?灵感来自于内置类型的写法:当我们观察任何运行时异常时,会发现它继承了RuntimeException,私有成员不能写,有两种构造方法。checkedexception的不同之处只是它继承了Exception,所以我们可以直接模仿它来写。一、自定义运行时异常二、自定义检查异常面试题:1、throw和throws有什么区别?2、finally中的语句会被执行吗?3、异常处理流程是怎样的?程序先执行try部分的正常流程-->如果try中出现异常,则结束try部分,从catch中查找是否有匹配的异常类,如果找到则执行try中的代码catch,如果没有找到,就向上传递给上层调用者-->如果调用者仍然匹配不到对应的异常类,就继续向上传递-->如果没有合适的异常类,直到main方法,会交给JVM处理,处理后程序终止;如果有finally语句,不管找到与否,都会执行finally中的语句
