JAVA项目中的常用的异常处理

Posted on 2019-11-03 22:09  九天龙凤  阅读(132)  评论(0编辑  收藏  举报

       异常 (Exception):发生于程序执行期间,表明出现了一个非法的运行状况。许多JDK中的方法在检测到非法情况时,都会抛出一个异常对象。例如:数组越界和被0除。而如果一个用户在运行程序期间由于程序错误无法再使用这个程序就十分糟糕。为了避免这类情况发生,至少应该做到以下几点:向用户通告错误;保存所有的工作结果;允许用户以妥善的方式退出。对于这样的处理方式,java称作异常处理。以上的处理方式具体到程序就是——返回到一种安全的状态,能让用户执行一些其他的命令;或者允许用户保存所有操作的结果,并以妥善的方式退出终止程序。要做到这些并不容易,因为错误的种类很多,想要检测错误条件的代码通常要离达到这个目标相去甚远,更何况每种错误有着不一样的处理方式。所以异常处理的任务是将控制权从错误产生的地方转移至能够处理错误的地方,而为了能处理这些问题,必须要研究程序中可能出现的问题和错误。异常处理的目的是依据实际情况提供不同的错误应对策略与手段,使程序更稳定,更安全。异常处理的主要用途是提供准确的错误消息,解释失败的原因、位置和错误类型等,同时提供一定的恢复能力,尽可能地保证数据完整性不被破坏,并让程序能继续运行。

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

       使用Java异常处理机制:把可能会发生错误的代码放进try语句块中。当程序检测到出现了一个错误时会抛出一个异常对象。异常处理代码会捕获并处理这个错误。catch语句块中的代码用于处理错误。当异常发生时,程序控制流程由try语句块跳转到catch语句块。不管是否有异常发生,finally语句块中的语句始终保证被执行。如果没有提供合适的异常处理代码,JVM将会结束掉整个应用程序。

       JDK中与异常相关的类

      

        Java中的异常分类:Throwable类有两个直接子类:Exception:出现的问题是可以被捕获的;Error:系统错误,通常由JVM处理。可捕获的异常又可以分为两类:(1)Check异常:直接派生自Exception的异常类,必须被捕获或再次声明抛出(2)Runtime异常:派生自RuntimeException的异常类。使用throw语句可以随时抛出这种异常对象: throw new ArithmeticException(…);

        跟踪异常的传播路径:当程序中出现异常时,JVM会依据方法调用顺序依次查找有关的错误处理程序。可使用printStackTrace 和 getMessage方法了解异常发生的情况:printStackTrace:打印方法调用堆栈。每个Throwable类的对象都有一个getMessage方法,它返回一个字串,这个字串是在Exception构造函数中传入的,通常让这一字串包含特定异常的相关信息。

        Error——OOM Error:在Android应用(它也使用Java开发)中,我们会经常碰到另一个Error,就是 “OutOfMemoryError”,表示系统内存不足,这个Error简写为“OOM Error”。Android应用之所以经常发生OOM,其原因在于手机的内存有限,在处理大图片等耗费大量内存资源的工作时,会耗尽可用内存。与一般Error不太一样,在Android应用中通常需要catch OOM并手动释放内存,以避免Android强制结束引发OOM的应用程序。

        “finally”的功用:资源泄露:当一个资源不再被某应用程序使用,但此程序并未向系统声明不再使用此资源时发生这种情况finally语句块主要用于解决资源泄露问题,它位于catch语句块之后,JVM保证它们一定执行。注意:finally语句块中也可能发生异常,如果这种情况发生,先前的异常被放弃。特别注意:当有多层嵌套的finally时,异常在不同的层次抛出 ,在不同的位置抛出,可能会导致不同的finally语句块执行顺序。

        受控与不受控的异常:throws语句表明某方法中可能出现某种(或多种)异常,但它自己不能处理这些异常,而需要由调用者来处理。当一个方法包含throws子句时,需要在调用此方法的代码中使用try/catch/finally进行捕获,或者是重新对其进行声明,否则编译时报错。throws语句中声明的异常称为受控(checked)的异常,通常直接派生自Exception类。RuntimeException(其基类为Exception)和Error(基类为Throwable)称为非受控的异常。这种异常不用在throws语句中声明。CheckedExceptionDemo.java示例展示了上述两种异常的特性。

        在实际开发中,选择正确的异常处理策略非常重要 ,它是系统健壮性的重要保证。在长期的软件开发实践中,人们己经总结出了多种 切实可行的异常处理方法和策略,在本讲中,我们介绍一种被广泛使用的异常处理方法——通过自定义异常类捕获并处理业务逻辑错误 。自定义异常通常选择直接派生自Exception:Class MyException extends Exception{ …    }。在合适的地方使用throw语句抛出自定义异常对象:Class MyClass {void someMethod() { if (条件) throw new MyException(); } }

        关于开发中异常处理的建议:在中间层组件中抛出异常,在界面层组件中捕获异常在底层组件中捕获JVM抛出的“只有程序员能看懂的”异常,转换为中间层的业务逻辑异常,再由界面层捕获以提供有意义的信息。
自身能够处理的异常,不要再向外界抛出。尽可能地在靠近异常发生的地方捕获并处理异常。尽可能地捕获最具体的异常类型,不要在中间层用 catch(Exception)“吃掉”所有异常。在开发阶段捕获并显示所有异常信息,发布阶段要移除部分代码,以避免“过于专业”的异常信息困扰用户,特别地,系统发布之后,不要将服务端异常的详细信息发给客户端,以免被黑客利用。