精华内容
下载资源
问答
  • Java异常处理

    千次阅读 2018-07-25 20:25:50
    处理反馈、业务异常、代码错误 在开发业务系统中,我们目前绝大多数采用MVC模式,但是往往有人把service跟controller紧紧的耦合在一起, 甚至直接使用Threadlocal来隐式传值,并且复杂的逻辑几乎只能使用service中存储...

    处理反馈、业务异常、代码错误

    在开发业务系统中,我们目前绝大多数采用MVC模式,但是往往有人把service跟controller紧紧的耦合在一起,

    甚至直接使用Threadlocal来隐式传值,并且复杂的逻辑几乎只能使用service中存储的全局对象来传递处理结果,

    包括异常.这样一来首先有违MVC模式,二来逻辑十分不清晰,难以维护。

    常常面临着这样的问题:

    • 系统运行出错,但是完全不知道错误发生的位置.
    • 我们找到了错误的位置,但是完全不知道是因为什么.
    • 系统明明出了错误,但是就是看不到错误堆栈信息.

    理由:

    经常看到一些项目,在全局定义一个 AppException,然后所有地方都只抛出这个异常,并且把捕获的异常case到这个AppException中.会有如下问题:

    • 浪费log日志存储空间,并且栈顶并不是最接近发生异常的代码位置.
    • 只有一种异常类,无法精准区分开异常类型
    • 异常类后期难以修改以增加其携带的信息.

     

    需要手动处理异常:

    • 你有能力处理异常,并且你知道如何处理
    • 你有责任处理异常

     

    自定义业务异常

         -考虑如下场景: 系统提供一个API,用于修改用户信息,服务器端采用json数据交互.

         -首先我们定义ServiceException,用来表示业务逻辑受理失败,它仅表示我们处理业务的时候发现无法继续执行下去.

    一个业务系统不可能不对用户提交的数据进行验证,验证包括两方面 : 有效性合法性,

    • 有效性: 比如用户所在岗位,是否属于数据库有记录的岗位ID,如果不存在,无效.
    • 合法性: 比如用户名只允许输入最多12个字符,用户提交了20个字符,不合法.

    合法性检查,可以交给java的校验框架执行,比如JSR303.

    1. 要修改的用户ID不存在.
    2. 用户被锁定,不允许修改.
    3. 乐观锁机制发现用户已经被被人修改过.

    对于前3种,我们认为是有效性检查失败,

    1. 由于某种原因,我们的程序无法保存到数据库.<属于我们无法处理的异常>
    2. 一些程序员错误的开发了代码,导致保存过程中出现异常,比如NPE.<程序员bug.>

     

    现在的问题是,前三种情况我们如何通知用户呢?

    1. 在controller 调用userService的checkUserExist()方法.
    2. 在controller直接书写业务逻辑.
    3. 在service响应一个状态码机制,比如1 2 3表示错误信息,0 表示没有任何错误.

    显然前2种方法都不可取 ,因为MVC设计模式告诉我们,controller是用来接收页面参数,并且调用逻辑处理,最后组织页面响应的地方.我们不可以在controller进行逻辑处理,controller只应该负责用户API入口和响应的处理(如若不然,思考一下如果有一天service的代码打包成jar放到另一个平台,没有controller了,该怎么办?)

    状态码机制是个不错的选择,可是如此一来,用户保存逻辑变了,比如增加一个情况,不允许修改已经离职的用户,那么我们还需要修改controller的代码,代码量增加,维护成本增高,并且还耦合了service,不符合MVC设计模式.

     

    这样一来只要我们检查到不允许保存的项目,我们就可以直接throw 一个新的异常,异常机制会帮助我们中断代码执行.

    接下来有2种选择:

    1. 在controller 使用try-catch进行处理.

         第1种方式是不可取的 ,注意我们抛出的ServiceException,它仅仅逻辑处理异常,并且我们的方法前面没有声明throws ServiceException,这表示他是一个非受查异常.controller也没有关心会发生什么异常.

         为什么不定义成受查异常呢? 如果是一个受查异常,那么意味着controller必须要处理你的异常.并且如果有一天你的业务逻辑变了,可能多一种检查项,就需要增加一个异常,反之需要删除一个异常,那么你的方法签名也需要改变,controller也随之要改变,这又变成了紧耦合,这和用状态码123表示处理结果没有什么不同.

         我们可以为每一种检查项定义一个异常吗? 可以,但是那样显得太多余了.因为业务逻辑处理失败的时候,根据我们需求,我们只需要通知用户失败的原因(通常应该是一段字符串),以及服务器受理失败的一个状态码(有时可能不需要状态码,这要看你的设计了),这样这需要一个包含原因属性的异常即可满足我们需求.

         2.直接把异常抛给上层框架统一处理.

          最后我们决定这个异常继承自RuntimeException.并且包含一个接受一个错误原因的构造器,这样controller层也不需要知道异常,只要全局捕获到ServiceException做统一的处理即可,这无论是在struct1,2时代,还是springMVC中,甚至servlet年代,都是极为容易的!

    自定义异常不提供无参构造器 ,因为绝对不允许你抛出一个逻辑处理异常,但是不指明原因,想想看,你是必须要告诉用户为什么受理失败的!

     

    注意一点,在这个类中,我们定义了2个log对象,分别指向 ServiceException.class 和 ModuleControllerAdvice.class . 并且处理 ServiceException的时候使用了info级别的日志输出,这是很有用的.

    • 首先,ServiceException一定要和其他的代码错误分离,不应该混为一谈.
    • 其次,ServiceException并不一定要记录日志,我们应该提供独立的log对象,方便开关.

    接下来你可以在修改用户的时候想客户端响应这样的JSON

    如此一来没有任何地方需要关心异常,或者业务逻辑校验失败的情况.用户也可以得到很友好的错误提示.

    如何对异常进行分类

    如果你只需要一句概括,那么直接定义一个简单的异常,用于中断处理,并且与用户保持友好交互即可.

    如果不可能一句话描述清楚,并且包含附加信息,比如需要在日志或者数据库记录消息ID,此时可能专门针对这种重要/复杂业务创建独立异常.

    上述两种情况因为web系统,是用户发起请求之后需要等待程序给予响应结果的.

     

     

    如果是后台作业,或者复杂业务需要追溯性.这种通常用流程判断语句控制,要用异常处理.我们认为这些流程判断一定在一个原子性处理中.并且检查到(不是遇到)的问题(不是异常)需要记录到用户可友好查看的日志.这种情况属于处理反馈,并不叫异常.

    综上,笔者通常分为如下几类:

    1. 逻辑异常,这类异常用于描述业务无法按照预期的情况处理下去,属于用户制造的意外.
    2. 代码错误,这类异常用于描述开发的代码错误,例如NPE,ILLARG,都属于程序员制造的BUG.
    3. 专有异常,多用于特定业务场景,用于描述指定作业出现意外情况无法预先处理.

    各类异常必须要有单独的日志记录,或者分级,分类可管理.有的时候仅仅想给三方运维看到逻辑异常.

    业务逻辑检查,也是意外情况

    UnknownHostException,表示找不到这样的主机,这个异常和NoUserException有什么区别么?

    换言之,没有这样的主机是异常,没有这样的用户不是异常了么?

    所以一定要弄明白什么是用异常来控制逻辑,什么是定义程序异常.

    异常处理效率很低

    书中所示的例子,是在循环中大量使用try-catch进行检查,但是业务系统,用户发起请求的次数与该场景天壤地别.淘宝的11`11是个很好的反例.但是请你的系统上到这个级别再考虑这种问题.

    1. 系统有千万并发,不可能还去考虑这些中规中矩的按部就班的方式,别忘了MVC本来就浪费很多资源,代码量增加很多.
    2. 业务系统也存在很多巨量任务处理的情况.但是那些任务都是原子性的,现在MVC中的controller和service可不是原子性的,不然为什么要区分这么多层呢.
    3. 如果那么在乎效率,考虑下重写Throwable的fillStackTrace方法.你要知道异常的开销大到底大在什么地方,fillStackTrace是一个native方法,会填充异常类内部的运行轨迹.

    上述代码就是典型的使用异常来处理业务逻辑.这种方式需要严重的禁止!

    上述代码最大的问题在于,我们如何利用异常来自动处理事务呢?

    然而这和我们的异常中断service没有什么冲突.也并不是一回事.

    • 我们提倡在 业务处理 的时候,如果发现无法处理直接抛出异常即可.
    • 而并不是在 逻辑处理 的时候,用异常来判断逻辑进行的状况.

    最后俏皮一句:微服务横行的今天,我们在action里面直接写业务处理,也无可厚非.

     

    展开全文
  • java异常处理

    万次阅读 2018-02-14 17:54:11
    java异常处理 java异常体系 Java的所有异常继承自Throwable,分为error(错误)和Exception(异常),Exception又分为可查异常和不可查异常,可查异常指的是编译器可以检查处理来,在编写代码的时候需要进行处理...

    java异常处理

    java异常体系

    异常体系

    Java的所有异常继承自Throwable,分为error(错误)和Exception(异常),Exception又分为可查异常不可查异常,可查异常指的是编译器可以检查处理来,在编写代码的时候需要进行处理,不可查异常指的是运行时异常例如NullException(空指针异常)在编写代码的时候可以不处理;error一般是jvm(虚拟机)错误不能处理,异常指的是一般可以被程序处理。

    try catch finally

    分析一下代码,说明输出:

    示例一

    package xuelongjiang.baseGrama.exceptiondeal;
    
    /**
     * @Author xuelongjiang
     */
    public class SimpleException {
    
    
        public static void main(String[] args) {
    
            SimpleException simpleException = new SimpleException();
    
            System.out.println(simpleException.exceptionTest(0));
        }
    
        public int  exceptionTest(int a2) {
    
            System.out.println("a2除数:"+a2);
             int a1  = 0;
    
             try {
             a1 = 10/a2;
             System.out.println("处理正常。。。。。");
             return a1;
    
             }catch (Exception e){
                 System.out.println("异常被抓住了。。。。。");
                 return 0;
             }finally {
                 System.out.println("进入finaly。。。。。");
                 System.out.println("a1:"+a1);
                 return 100;
             }
        }
    
    }
    

    输出结果:

    a2除数:0

    异常被抓住了。。。。。

    进入finaly。。。。。

    a1:0

    100

    示例二

    package xuelongjiang.baseGrama.exceptiondeal;
    
    /**
     * @Author xuelongjiang
     */
    public class SimpleException {
    
    
        public static void main(String[] args) {
    
            SimpleException simpleException = new SimpleException();
            try {
                System.out.println(simpleException.exceptionTest(0));
    
            }catch (Exception e){
                System.out.println("最外层的catch。。。。");
            }
    
    
        }
    
        public int  exceptionTest(int a2) throws  Exception {
    
            System.out.println("a2除数:"+a2);
             int a1  = 0;
    
             try {
             a1 = 10/a2;
             System.out.println("处理正常。。。。。");
             return a1;
    
             }catch (Exception e){
                 System.out.println("异常被抓住了。。。。。");
                 throw  e;
                 //return 0;
             }finally {
                 System.out.println("进入finaly。。。。。");
                 System.out.println("a1:"+a1);
                 return 100;
             }
        }
    
    }
    
    

    输出:

    a2除数:0

    异常被抓住了。。。。。

    进入finaly。。。。。

    a1:0
    100

    示例三

    package xuelongjiang.baseGrama.exceptiondeal;
    
    /**
     * @Author xuelongjiang
     */
    public class SimpleException {
    
    
        public static void main(String[] args) {
    
            SimpleException simpleException = new SimpleException();
            try {
                System.out.println(simpleException.exceptionTest(0));
    
            }catch (Exception e){
                System.out.println("最外层的catch。。。。");
            }
    
    
        }
    
        public int  exceptionTest(int a2) throws  Exception {
    
            System.out.println("a2除数:"+a2);
             int a1  = 0;
    
             try {
             a1 = 10/a2;
             System.out.println("处理正常。。。。。");
             return a1;
    
             }catch (Exception e){
                 System.out.println("异常被抓住了。。。。。");
                 throw  e;
                 //return 0;
             }finally {
                 System.out.println("进入finaly。。。。。");
                 System.out.println("a1:"+a1);
                 //return 100;
             }
        }
    
    }
    

    输出:

    a2除数:0

    异常被抓住了。。。。。

    进入finaly。。。。。

    a1:0

    最外层的catch。。。。

    根据以上代码给出结论:

    如果有finally即使try 和catch中有return也不会返回,而是返回finally中的return
    如果finally中没有return语句,并且try和catch中有返回语句或throw那么会执行try,catch中的返回

    throw throws

    在上面的示例中,我们看到了throws和throw的用法,有时方法没有能力处理异常,需要向上抛出异常,由其他方法来处理异常。

    throw 检查异常处理的时候,如果使用throw 那么必须使用throws .
    throw 用于方法中, thows用于方法的签名。

    总结

    如果异常处理太多会影响正常代码的阅读,一般建议专门有个异常处理的方法,来处理异常。而产生异常的方法只需要抛出代码,这样能极大的方便阅读代码,及整洁代码。

    展开全文
  • java异常处理(较详细)

    千次阅读 多人点赞 2020-02-21 17:30:34
    java异常处理(较详细) 在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的。 比如: 客户输入数据的格式, 读取文件...

    在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的。
    比如: 客户输入数据的格式, 读取文件是否存在, 网络是否始终保持通畅等等。

    异常:在Java语言中, 将程序执行中发生的不正常情况称为“异常” 。
    (开发过程中的语法错误和逻辑错误不是异常)
    Java程序在执行过程中所发生的异常事件可分为两类:

    • Error: Java虚拟机无法解决的严重问题。 如: JVM系统内部错误、 资源耗尽等严重情况。
      比如: StackOverflowError和OOM。 一般不编写针对性的代码进行处理。
    • Exception: 其它因编程错误或偶然的外在因素导致的一般性问题, 可以使用针对性的代码进行处理。 例如:
      1、空指针访问
      2、试图读取不存在的文件
      3、网络连接中断
      4、数组角标越界

    对于这些错误, 一般有两种解决方法:
    一种是遇到错误就终止程序的运行。
    一种方法是由程序员在编写程序时, 就考虑到错误的检测、 错误消息的提示, 以及错误的处理。

    • 捕获错误最理想的是在编译期间, 但有的错误只有在运行时才会发生。
      比如: 除数为0, 数组下标越界等
      分类: 编译时异常和运行时异常

    1.运行时异常
    是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。 java.lang.RuntimeException类及它的子类都是运行时异常。
     对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。

    2.编译时异常
    是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。
    编译器要求Java程序必须捕获或声明所有编译时异常。
    对于这类异常,如果程序不处理,可能会带来意想不到的结果。

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

    在编写程序时,经常要在可能出现错误的地方加上检测的代码,
    如进行x/y运算时,要检测分母为0,数据为空,输入的不是数据而是字符等。
    过多的if-else分支会导致程序的代码加长、臃肿,可读性差。因此采用异常处理机制。

    Java异常处理
    Java采用的异常处理机制,是将异常处理的程序代码集中在一起,与正常的程序代码分开,
    使得程序简洁、优雅, 并易于维护。

    java异常处理的方式:
    方式一: try-catch-finally
    方式二: throws + 异常类型

    Java提供的是异常处理的抓抛模型。
    过程一:Java程序的执行过程中如出现异常, 会生成一个异常类对象,该异常对象将被提交给Java运行时系统, 这个过程称为抛出(throw)异常。
    过程二:抓,可以理解为异常的护理方式。

    异常对象的生成
    由虚拟机自动生成:程序运行过程中,虚拟机检测到程序发生了问题,如果在当前代码中没有找到相应的处理程序,就会在后台自动创建一个对应异常类的实例对象并抛出——自动抛出
    由开发人员手动创建: Exception exception = new ClassCastException();——创建好的异常对象不抛出对程序没有任何影响,和创建一个普通对象一样。
    在这里插入图片描述如果一个方法内抛出异常, 该异常对象会被抛给调用者方法中处理。
    如果异常没有在调用者方法中处理, 它继续被抛给这个调用方法的上层方法。
    这个过程将一直继续下去, 直到异常被处理。这一过程称为捕获(catch)异常。
    如果一个异常回到main()方法, 并且main()也不处理, 则程序运行终止。
    程序员通常只能处理Exception, 而对Error无能为力。
    异常处理是通过try-catch-finally语句实现的。
    在这里插入图片描述try
    捕获异常的第一步是用try{…}语句块选定捕获异常的范围, 将可能出现异常的代码放在try语句块中。在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配。 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常处理,一旦处理完成就跳出当前的try-catch结构(在没有写finally的情况下)。继续执行其后的代码。在try结构中声明的变量,出了try结构之后,就不能被调用。

    catch (Exceptiontype e)
    在catch语句块中是对异常对象进行处理的代码。 每个try语句块可以伴随一个或多个catch语句, 用于处理可能产生的不同类型的异常对象。catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓,如果异常类型满足子父类的关系,则要求子类一定要声明在父类的上面,否则报错。

    finally
    捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。
    不论在try代码块中是否发生了异常事件, catch语句是否执行, catch语句是否有异常, catch语句中是否有return,finally块中的语句都会被执行。
    finaly中声明的是一定会被执行的代码,即使catch中出现了异常,try中有return语句,catch中有return语句等情况。
    finally语句和catch语句是任选的。
    像数据库连接,输入输出流,网络编程socket等资源,JVM是不能自动回收的,我们需要手动的进行资源的释放。此时的资源的释放,就需要声明在finally中。

    注意:
    如果明确知道产生的是何种异常, 可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。
    比 如 : 可 以 用 ArithmeticException 类 作 为 参 数 的 地 方 , 就 可 以 用RuntimeException类作为参数, 或者用所有异常的父类Exception类作为参数。但不能是与ArithmeticException类无关的异常, 如NullPointerException(catch中的语句将不会执行) 。使用try-cathch-finally处理编译时异常,使得程序在编译时不在报错,但在运行时,仍有可能报错。相当我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现。
    try-catch-finally结构可以相互嵌套。

    捕获异常的有关信息:
    与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。
    getMessage() 获取异常信息,返回字符串
    printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
    在这里插入图片描述不捕获异常时的情况
    前面使用的异常都是RuntimeException类或是它的子类,这些类的异常的特点是:即使没有使用try和catch捕获, Java自己也能捕获,并且编译通过( 但运行时会发生异常使得程序运行终止 )。

    如果抛出的异常是IOException等类型的非运行时异常,则必须捕获,否则编译错误。也就是说,我们必须处理编译时异常,将异常进行捕捉,转化为运行时异常。

    异常处理机制二:throws +异常类型

    声明抛出异常是Java中处理异常的第二种方式
    throws +异常类型,写在方法的声明处,此时此方法执行时, 可能会抛出的类型。
    如果一个方法(中的语句执行时)可能生成某种异常, 但是并不能确定如何处理这种异常, 则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
    在方法声明中用throws语句可以声明抛出异常的列表, throws后面的异常类型可以是方法中产生的异常类型, 也可以是它的父类。
    一旦方法体执行时,出现异常,仍会在异常代码处,生成一个异常类的对象,此对象满足throws后异常类型是,就会被抛出。异常代码后续的代码,就不在执行。
    throws的方式只是将异常抛给了方法的调用者,并没有真正将异常处理掉。
    声明抛出异常举例:
    public void readFile(String file) throws FileNotFoundException {
    ……
    // 读文件的操作可能产生FileNotFoundException类型的异常
    FileInputStream fis = new FileInputStream(file);
    ………
    }

        public void method() {
              try {
                  test3();
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }
         }
         
         @Test
         public void test3() throws  FileNotFoundException,IOException {
              File file =new File("heool.txt");
              FileInputStream fis = new FileInputStream(file);
              
              int data = fis.read();
              while(data != -1) {
                  System.out.println((char)data);
                  data = fis.read();
              }
              fis.close();
         }
    }
    

    在这里插入图片描述重写方法声明抛出异常的原则
    重写方法不能抛出比被重写方法范围更大的异常类型。 在多态的情况下,
    对methodA()方法的调用-异常的捕获按父类声明的异常处理。

    
    public class A {
    public void methodA() throws IOException {
    ……
    } }
    public class B1 extends A {
    public void methodA() throws FileNotFoundException {
    ……
    } }
    public class B2 extends A {
    public void methodA() throws Exception { //报错
    ……
    } }
    

    如何选择try-catch和throws
    如果父类中被重写的方法中没有throws方式处理异常,则子类重写的方法中也不能使用throws,意味如果子类重写的方法中有异常,必须使用try-catch。
    执行的方法a中,先后又调用了另外的几个方法,这九个方法是递进关系执行的,我们建议这几个方法使用throws的方式进行处理。而执行的方法a可以考虑使用try-catch

    手动抛出异常
    java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出, 也可根据需要使用人工创建并抛出。
    首先要生成异常类对象, 然后通过throw语句实现抛出操作(提交给Java运行环境)。
    IOException e = new IOException();
    throw e;
    可以抛出的异常必须是Throwable或其子类的实例。 下面的语句在编译时将会产生语法错误:
    throw new String(“want to throw”);

    public class ExceptionTest3 {
         public static void main(String[] args) {
              try {
                  Student stu=new Student();
                  stu.register(-1003);
                  System.out.println(stu);
              } catch (Exception e) {
                  System.out.println(e.getMessage());
              }
         }
    }
    class Student{
         private int id;
         public void register(int id) throws Exception {
              if(id>0) {
                  this.id =id;
              }else {
                  //System.out.println("输入的id不合法");
                  //手动抛出异常
                  //throw new RuntimeException("你输入的数据不合法");
                  throw new Exception("输入的数据不合法");
              }
         }
         @Override
         public String toString() {
              return "Student [id=" + id + "]";
         }
    }
    

    用户自定义异常类
    一般地,用户自定义异常类都是RuntimeException的子类。
    自定义异常类通常需要编写几个重载的构造器。
    自定义异常需要提供全局常量:serialVersionUID
    自定义的异常通过throw抛出。
    自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。

    用户自定义异常类MyException,用于描述数据取值范围错误信息。用户自己的异常类必须继承现有的异常类。
    在这里插入图片描述在这里插入图片描述总结
    在这里插入图片描述一首小悟结束异常处理
    世界上最遥远的距离,是我在if里你在else里,似乎一直相伴又永远分离;
    世界上最痴心的等待,是我当case你是switch,或许永远都选不上自己;
    世界上最真情的相依,是你在try我在catch。无论你发神马脾气,
    我都默默承受,静静处理。到那时,再来期待我们的finally。

    来自bilibili尚硅谷宋红康老师笔记

    展开全文
  • java异常处理机制

    千次阅读 2021-01-11 19:42:29
    异常机制是指当程序出现错误后,程序如何处理。具体来说就是程序发生异常异常机制提供程序的退出安全通道。 通俗来说:就是为了让程序继续执行下去,不至于中断。 程序错误: 程序错误分为三种:1.编译错误 2....

    一、什么是异常

    异常机制:
    异常机制是指当程序出现错误后,程序如何处理。具体来说就是程序发生异常,异常机制提供程序的退出安全通道。

    通俗来说:就是为了让程序继续执行下去,不至于中断。

    程序错误:
    程序错误分为三种:1.编译错误 2.运行时错误 3.逻辑错误。
    (1)编译错误:因为程序没有遵循语法规则,编译程序能够自己发现并提示我们的错误的原因和位置。
    (2)运行时错误:因为程序在执行时,运行环境发现了不能执行的操作。
    (3)逻辑错误:因为程序没有按照预期的逻辑顺序执行。

    异常就是指程序运行时发生错误,而异常处理就是对这些错误进行处理和控制。

    编译错误如下:
    编译错误
    运行错误如下:
    运行异常
    算数异常报错:
    错误描述

    二、异常的结构图

    在这里插入图片描述
    常见异常:

    序号异常名称异常描述
    1java.lang.NullPointerException空指针异常:对象为空,并且调用相应方法。
    2java.lang.ClassNotFoundException找不到指定类
    3java.lang.ArrayIndexOutOfBoundsException数组下标越界
    4java.lang.NumberFormatException数字格式化异常
    5java.lang.ArithmeticException数学运算异常
    6java.lang.StackOverflowError内存空间溢出错误,方法递归调用中,经常发生
    7java.lang.ClassCastException类型转换异常,向下转型中经常发生
    8java.text.ParseException时间格式化异常,SimpleDateFormart中经常发生
    9java.util.InputMismatchException输入类型不匹配异常

    三、捕获异常

    虚拟机对异常的两种处理方式:
    1.捕获异常
    2.抛出异常

    1.捕获异常
    try - catch - finally

    1. try:尝试着执行可能会出现异常的代码
    2. catch:如果try中的代码在执行过程中,出现了异常,捕获该异常,如果没有异常,就不执行。
    3. finaliy:其中的代码块是不管报不报错都会执行的,通常用来释放资源。
    try{
        //可能会出错的代码块
    }catch(){
        //出现异常后,执行的语句
    }finally{
        //通常用来释放资源
    }
    

    四、声明和抛出异常

    1.使用throws声明异常

    ​ 运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常

    public void fun1() throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = format.parse("2020-10-12");
    }
    

    2.使用throw抛出异常

    ​ throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。

    public void fun2() {
         throw new NullPointerException("空指针异常");  
         System.out.println("hello world");//会报红,提示unreachable statement,该语句不可能被执行
    }
    

    案例:
    1、嵌套try-catch

    @Test
    public void fun2()  {
        try {
            throw new Exception("非运行时异常,哈哈哈");
        } catch (Exception e) {
            e.printStackTrace();
            try {
                throw new ParseException("解析异常,哈哈哈",0);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }finally {
            try {
                throw new TimeoutException("超时异常,哈哈哈");
            } catch (TimeoutException e) {
                e.printStackTrace();
                try {
                    throw new SQLException("SQL异常");
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
    

    2、代替返回语句

    public int  funR1(){
            try {
                return 1;
            }catch (Exception e){
               throw new RuntimeException();
            }
        }
    public int  funR2(){
        if(true) {
            return 1;
        }else{
            throw new RuntimeException();
        }
    }
    

    五、自定义异常

    自定义异常,通常就是定义了一个继承自Exception类的子类,那么这个类就是一个自定义异常类。通常情况下,我们都会直接继承自Exception,一般不会继承某个运行时异常类。

    案例如下:

    public class HeroNotExistException extends RuntimeException {
        private String m;
    
        public String getM() {
            return m;
        }
    
        public void setM(String m) {
            this.m = m;
        }
    //两个参数的有参构造,一个传递给父类Throwable,一个自己用
        public HeroNotExistException(String message, String m){
           super(message);
           this.m=m;
        }
    
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            System.out.println("请输入您最欣赏的历史人物:");
            String name = sc.next();
            if(name.equals("孙悟空")){
                try{
                    throw new HeroNotExistException("英雄人物不存在","哈哈");
                }catch (HeroNotExistException e){
                    e.printStackTrace();
                    System.out.println(e.getM());
                }
            }
        }
        
    }
    
    展开全文
  • Java异常处理机制

    千次阅读 2019-04-24 20:19:37
    作者:小符 撰写时间:2018.4.24 学会了异常处理可以帮助...Java异常处理机制为:抛出异常,捕捉异常,处理异常。 语法格式: try…catch 在使用try…catch捕获处理异常时需要注意: **·**不要过度使用异常,不能使...
  • Java异常处理简单实例

    千次阅读 2019-05-12 16:56:35
    Java异常处理 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error;如果你用System.out.println...
  • 高效的Java异常处理框架

    千次阅读 2017-03-14 22:02:50
    高效的Java异常处理框架 摘要:本文从Java异常最基本的概念、语法开始讲述了Java异常处理的基本知识,分析了Java异常体系结构,对比Spring的异常处理框架,阐述了异常处理的基本原则。并且作者提出了自己处理一...
  • JAVA异常处理最佳实战心得

    千次阅读 2018-09-28 16:42:12
    尤其是在各种服务相关的代码中,可能正常业务逻辑的代码量很少,大部分都是各种try catch处理各种异常的代码,因为实际中异常情况很多,为了保证服务的健壮与稳定性,要尽可能考虑与处理掉各种异常情况。所以在java...
  • 一、前言 异常是程序在运行时出现的不正常情况。这个问题按照面向对象思想进行描述,并封装成了对象。...异常就是Java按照面向对象的思想将问题进行对象封装。这样就方便于操作问题以及处理问题。
  • Java异常处理和异常抛出

    千次阅读 多人点赞 2019-02-21 13:11:44
    生活中的异常是指那些有异于常态,和正常情况...这时异常处理机制就很重要了,它会以适当的方法让程序继续执行或者退出,并且能够保存用户的当前操作或者进行数据回滚,最后再把占用的资源释放掉。 一.Java异常体系...
  • Java异常处理习题

    万次阅读 2017-10-05 17:45:16
    1、java中用来抛出异常的关键字是( ) A.try B.catch C.throw D.finally   2、关于异常,下列说法正确的是( ) A. 异常是一种对象 B.一旦程序运行,异常将被创建 C.为了保证程序运行速度,要尽量避免...
  • Java异常处理终结篇——如何进行Java异常处理设计

    万次阅读 多人点赞 2014-02-28 15:08:57
    使用Java异常的人很多,但能合理使用的却不多,Java异常处理设计是一个冷门的话题,但好的异常设计会让程序有质的变化,所以本文从各个方面分析便总结了,在Java程序中,如何进行异常设计。
  • JAVA异常处理原理

    千次阅读 2018-05-25 22:54:05
    一、Java异常处理机制的优点在一些传统的编程语言,如C语言中,并没有专门处理异常的机制,程序员通常用方法的特定返回值来表示异常情况,并且程序的正常流程和异常流程都采用同样的流程控制语句。Java语言按照面向...
  • 如果在继承中,子类如何处理异常?这两个问题,我们这篇来总结下,然后来几个异常的练习题。1.异常注意事项- 子类重写父类方法时,子类的方法必须抛出相同的异常或者父类异常的子类。(父亲坏了,儿子不能更坏)- ...
  • 那么,java程序中的异常我们可以捕获然后处理,这样后面的程序就可以继续执行了; 上代码: package m12d28; public class ExceptionDemo01 { public static void main(String[] args) ...
  • Java异常处理个人心得总结

    千次阅读 2018-10-09 20:42:35
    1、异常处理的流程总是首先抛出异常,然后才进行处理 public class TestException { public static void main(String[] args) { int a = 6; int b = 0; try { // try监控区域 if (b == 0) throw new...
  • Java异常处理(代码演示)

    千次阅读 2019-04-22 22:28:09
    * 异常处理 * * 1.Throwable是异常的基类,分为Error和Exception,在编程中我们关注Exception * 2.Exception分为编译期异常(受检)和运行期异常(非受检) 3.异常会导致程序中断,无法继续执行 * 4...
  • 作者:Maverick ... 1. 课前练习 ...如果不能找出至少两处错误,说明你还是一个“菜鸟”,对JAVA异常处理机制还不够了解,需要仔细阅读本文的内容,并走查一下自己编写的代码。如果你可以找出至少两处错误,恭
  • Java 异常处理(自定义异常处理

    千次阅读 2018-07-16 19:25:15
    异常处理分为两种: 1、系统异常处理 2、自定义异常处理 下面分别来讲解小编对这个的理解 1、系统异常处理 public class Abnormal { public static void main(String args[]) { Person person = new Person...
  • java异常处理的五个关键字

    千次阅读 2017-10-24 22:51:24
    传送门
  • java异常处理常用关键字

    千次阅读 2019-08-06 20:04:39
    异常处理两种方式: 1、捕获异常:try catch 直接处理可能出现的异常! 2、声明异常:throws 声明告诉调用者可能的异常,暴露问题,调用者自己处理! 异常处理的5 个关键字: try, catch, finally throw, throws...
  • java 异常处理之声明抛出异常

    千次阅读 2018-11-01 00:44:38
    java 异常处理声明抛出异常2.声明抛出异常是Java中处理异常的第二种方式 2.声明抛出异常是Java中处理异常的第二种方式 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此...
  • java异常处理之try...catch...finally详解

    千次阅读 2017-07-17 22:11:51
    异常处理机制已经成为判断一门编程语言是否...一.java继承体系 Java语言为异常处理提供了丰富的异常类,这些类之间有严格的继承关系。如图: 从图中我们可以看出,所有的类都是继承于Throwable这个父类,java将所有
  • 对于程序运行过程中的可能出现异常情况,java语言使用一种称为异常处理的错误捕捉机制进行处理。相信大家对 try { }catch( ){} finally{} 这种结构非常熟悉,使用频率极高。既然经常使用它,而且也是面试常问知识点...
  • java 异常处理之自定义一个异常类1.定义异常类2.dome3.异常类继承关系图 1.定义异常类 自定义的异常类继承现有的异常类 提供一个序列号,作为对象的唯一标识 提供几个重载的构造器 自己或间接继承...
  • Java异常处理-原则

    千次阅读 2016-04-12 17:26:56
    异常处理重要原则:只有在你知道如何处理的情况才捕获异常,否则就往上抛出异常3.异常处理目标:把错误处理代码同错误发生的地点分离4.只能忽略RuntimeException(及其子类)类型异常,其他类型异常的处理都是有...
  • Java异常处理流程

    千次阅读 多人点赞 2019-09-29 10:56:56
    Java应用中,异常处理机制分为抛出异常和捕获异常。 文章目录1. 抛出异常2. 捕获异常3. 异常的抛出与捕获3.1 直接抛出异常3.2 封装异常再抛出3.3 捕获异常3.4 自定义异常3.5 try-catch-finally3.6 try-with-...
  • Java异常处理的五个关键字

    万次阅读 2018-02-09 14:15:35
    (..•˘_˘•..) 版权声明:转载原创文章请以超链接形式请...异常处理关键字:try、catch、finally、throw、throws注意事项:1、错误不是异常,而是脱离程序员控制的问题。2、所有的异常类是从 java.lang.Exceptio...
  • java异常处理之Scanner整数接受异常

    千次阅读 2016-11-30 15:51:31
    java异常练习的时候,有这样一个问题:  如题: 1. 写一个方法,从键盘输入一个整数,如果输入的不是整数,则提示输入有误,请重新输入,直到输入正确为止。 分析如下:使用Scanner的nextInt时,如果...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 812,152
精华内容 324,860
关键字:

java异常处理

java 订阅