异常处理

Java 异常处理

区分Exceptio(异常)和Error(错误),异常可以捕获,而错误不能

异常通常分为三大类

1.用户输入非法的数据

2.要打开的文件不存在

3.网络通信连接中断,或者JVM内存溢出

要理解Java异常处理是如何工作的,需要掌握以下三种类型的异常:

  • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
  • Exception 类的层次

    所有的异常类是从 java.lang.Exception 类继承的子类。

    Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。

    Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。

    Error 用来指示运行时环境发生的错误。

    例如,JVM 内存溢出。一般地,程序不会从错误中恢复。

    异常类有两个主要的子类:IOException 类和 RuntimeException 类。

  • Check异常:直接派生自Exception的异常类,必须被捕获或再次声明抛出
  • Runtime异常:派生自RuntimeException的异常类,使用throw语句可有随时抛出这种异常现象
  •  

     

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

方法一为捕获异常,方法二为抛出异常

        Try{
            //可能发生运行错误的代码;
        }
        catch(异常类型     异常对象引用){
            //用于处理异常的代码
        }
        finally{
            //用于“善后” 的代码
        }

运行过程,如果try的代码抛出了一个异常便会停止运行直接跳到catch捕获这个异常,如果没有合适的异常处理代码,JVM就会结束整个应用程序,而finally里的语句,无论sfou-发生异常最终都将被执行

try{…}语句块选定捕获异常的范围

 每个try语句块可以伴随一个或多个catch语句, 用于处理可能产生的不同类型的异常对象。catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓,如果异常类型满足子父类的关系,则要求子类一定要声明在父类的上面,否则报错(因为可能会重复捕获同一个异常,为语法错误,一个异常只能捕获一次),一旦某个catch语句捕获到了异常,下面的catch就不会执行了

finally捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。

不论在try代码块中是否发生了异常事件, catch语句是否执行, catch语句是否有异常, catch语句中是否有return,finally块中的语句都会被执行。

finaly中声明的是一定会被执行的代码,即使catch中出现了异常,try中有return语句,catch中有return语句等情况,但是如果try之前有return的情况finally就不会被执行。

finally语句和catch语句是任选的。

像数据库连接,输入输出流,网络编程socket等资源,JVM是不能自动回收的,我们需要手动的进行资源的释放。此时的资源的释放,就需要声明在finally中。

throws +异常类型

throws +异常类型,写在方法的声明处,此时此方法执行时, 可能会抛出的类型。

如果一个方法(中的语句执行时)可能生成某种异常, 但是并不能确定如何处理这种异常, 则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
在方法声明中用throws语句可以声明抛出异常的列表, throws后面的异常类型可以是方法中产生的异常类型, 也可以是它的父类。
一旦方法体执行时,出现异常,仍会在异常代码处,生成一个异常类的对象,此对象满足throws后异常类型是,就会被抛出。异常代码后续的代码,就不在执行。
throws的方式只是将异常抛给了方法的调用者,并没有真正将异常处理掉。

因此在调用此方法时需要用try语句捕获,或者是重新对其进行声明,否则编译时报错

一个子类的throws子句抛出的异常,不能是其基类同名方法抛出的异常对象的父类

异常嵌套

 异常处理流程代码可以放在任何能放可执行性代码的地方,因此完整的异常处理流程既可放在try块里,也可放在catch块里,也可放在finally块里。

  异常处理嵌套的深度没有明确的限制,但通常没有必要使用超过两层的嵌套异常处理,层次太深的嵌套异常处理没有太大必要,而且导致程序可读性降低。

异常处理原则:

    不要过度使用异常;

    不要使用过于庞大的try块;

    避免使用Catch AII 语句;

    不要忽略捕获到异常。

printStackTrace:打印方法调用堆栈

每个Throwable类的对象都有一个getMessage方法,它返回一个子串,这个字串是在Exception构造函数中传入,通常让这一字串包含特定异常相关信息

 

posted @ 2022-10-17 18:21  突破铁皮  阅读(142)  评论(0编辑  收藏  举报