在可能会出现exception的地方,要使用try-catch或者throws或者两者都要。我的判断依据是:如果对可能出现的exception不想被外部(方法的调用者)知道,就在方法内部try-catch掉这个exception;如果希望外部知道,则在catch到之后把exception直接抛出或者抛出自定义的exception。


一、异常的种类  
java异常可以分成两大类:Exception和RuntimeException(虽然RuntimeException是从Exception继承的)。exception异常代表“无法避免的异常” 如io异常   往往这类异常是由于外部原因造成的,程序本身无法保证他们不发生,所以这类异常必须捕获。如果在函数内部无法处理这个异常必须再次抛出(在函数后面用throws语句),如果什么都不做就出现编译错误。
runtimexception是指“可以避免的异常”,如 null引用异常,这类异常都是由程序内部原因造成的,是可以避免的。对于这类异常可以忽略他们,但一旦发生程序就会异常终止。这类异常对debug非常有帮助,当然,如果需要也可以catch。

另外,有些地方即使不会有exception,但是从商业逻辑上是错误的、非预期的,也可以抛出user exception。例如,用户输入非法,bank account非法透支等等。

二、主要原则  
处理意外的一个重要原则,就是要么处理,要么接着抛,决不能吃掉(You either handle it, or throw it. You don’t eat it.)这就是说,当你捕获一个异常之后,必须决定是否立即处理这个异常,或者继续抛出这个异常(或者另一个自定义异常),以便由调用的客户端捕获之。当客户端捕获到以后,又会继续进行类似的判断。

一般来说,GUI端是要处理异常的,比如JSP捕获到异常之后,需要先是给用户一个友好的出错信息,而不要给出系统的出错信息。系统的出错信息一方面不太友好,另一方面提供了太多的系统信息,容易被恶意用户用来攻击系统。

换句话说,所有的异常最终必须有一个终极的处理者,这就是GUI。至于中间的环节,比如在服务器端运行的JavaBean是否要处理捕获到的异常,还是继续抛出所捕获的异常,需要视具体情况处理。

除非你想把异常处理的责任交给调用者,一般不用throws。 比如你要读入一些文件,如果你想通知调用者,让调用者决定如何处理这个异常,你就把这个异常throws给调用者;如果你知道应该如何处理这个异常,或者你想把异常马上解决,你可以就地catch她。

这完全取决于你想把异常自己立即处理还是想把处理责任返回给调用者。取决于你的程序的结构和要求。  
需要注意的有:
1、如果无法处理某个异常,那就不要捕获它。  
2、如果捕获了一个异常,请不要胡乱处理它。  
3、尽量在靠近异常被抛出的地方捕获异常。  
4、在捕获异常的地方将它记录到日志中,除非您打算将它重新抛出。  
5、按照您的异常处理必须多精细来构造您的方法。  
6、需要用几种类型的异常就用几种,尤其是对于应用程序异常。

三、异常嵌套和捕获适当的异常

按照Java语言的定义,所谓异常(Exception)指的就是向调用方法(calling method)表示发生非正常情况的习惯方式。下面讨论两种在处理异常时可兹利用的技术:异常嵌套和捕获适当的异常。

异常嵌套  
你在试图捕获异常并打算扔出异常时该采取什么措施呢?同时,你希望原始的异常信息可用吗?

要回答以上的问题你不妨尝试一下NestedException类。具体的编程并不难,唯一要做的无非是利用构造器并且重载printStackTrace()以便显示出正确的数据。

此外,你还应当考虑封装Throwable而非Exception类来创建更具有重用性的组件。之后,你可以创建NestedRuntimeException变量封装Throwable但无需对其进行声明。

捕获适当的异常
正确地处理异常并不是一项轻松的任务,这是因为异常的处理有时会导致程序出现其他不明行为。不过,以下三条规则可以帮助你避免错误处理异常所可能遭遇的风险。

规则 #1: 总是捕获扔出异常的类型而不要理睬异常的超类。 为了遵守通常的代码习惯,你可以采用Exception类的大写字母作为变量名,如下所示:  
    catch(FileNotFoundException fnfe)  
以及
    catch(SQLException sqle)

规则 # 2: 决不让catch块留空。在很多情况下虽然确实编写了try/catch块但在代码的catch部分却什么都没有做。或者,如果采用了日志API(Logging API),那么请编写代码把异常写到日志中。

规则 # 3: 决不扔出Exception基类的实例。开发人员应当总是扔出自己创建的异常类。

扔出异常的API很难处理。在声明方法扔出java.lang.Exception的情况下,所有的问题都会强加在API用户的头上,这样他们就无法以一种专业的编程方式来处理异常。通过为扔出API声明Exception类的子类这一举措,API开发人员就可以减轻用户的负担。

**************************************************************************************************************************
finally总是会保证在最后执行,一般我们在里面处理一些清理的工作,比如关闭文件流或者数据库,网络等操作。

当然上面的语句块结构是灵活的,但是try是必须有的,catch和finally两者至少有一个,当然catche的数量可以有多个。有时候try语句块中可能抛出多种类型的异常,这个时候,我们可以写多个catch语句来捕获不同类型的异常,一个比较好的写法如下:

        try{
// ..invoke some methods that may throw exceptions
}catch(ExceptionType1 e){
//...handle exception
}catch(ExceptionType2 e){
//...handle exception
}catch(Exception e){
//...handle exception
}finally{
//..do some cleaning :close the file db etc.
}

【开发技术】java异常的捕获与抛出原则的更多相关文章

  1. JAVA异常的捕获与抛出原则

    在可能会出现exception的地方,要使用try-catch或者throws或者两者都要.我的判断依据是:如果对可能出现的exception不想被外部(方法的调用者)知道,就在方法内部try-cat ...

  2. 《Java基础——异常的捕获与抛出》

    Java基础--异常的捕获与抛出     '  前言: Error类(错误)和Exception类(异常)是Throwable类的子类. 异常分为CheckedException类(编译时异常)和Ru ...

  3. java基础16 捕获、抛出以、自定义异常和 finally 块(以及关键字:throw 、throws)

    1.异常的体系 /* ------|Throwable:所有异常和错误的超类 ----------|Error(错误):错误一般用于jvm或者硬件引发的问题,所以我们一般不会通过代码去处理错误的 -- ...

  4. 捕获Java线程池执行任务抛出的异常

    捕获Java线程池执行任务抛出的异常Java中线程执行的任务接口java.lang.Runnable 要求不抛出Checked异常, public interface Runnable { publi ...

  5. Effective Java 第三版——73.抛出合乎于抽象的异常

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  6. C# 异常 抛异常的时候 同时抛出 传入的参数

    abp的审计日志都把这些功能实现了 可以借鉴 抛异常的时候 同时抛出 传入的参数 大致这样实现,aop,方法执行先,先把参数写入到栈中,抛异常时,栈中自然就有此时的参数了. 可用于重现该异常. 获取把 ...

  7. java 异常的捕获及处理

    在没有异常处理的程序中如果要回避异常,需要使用大量的判断语句,配合所想到的错误状况来捕捉程序中可能发生的错误.但是这样势必会导致程序运行效率降低.java异常处理机制具有易于使用,可自定义异常类,处理 ...

  8. 菜鸡的Java笔记 第三十 - java 异常的捕获及处理

    异常的捕获及处理        1.异常的产生分析以及所带来的影响        2.异常的处理的基本格式        3.异常的处理流程        4.异常的处理模式        5.自定义 ...

  9. java 异常与捕获

    几乎所有的代码里面都会出现异常,为了保证程序在出现异常之后可以正常执行完毕,就需要进行异常处理. 先来看一下异常的继承类结构: 所有的异常都是由Throwable继承而来,我们来看他下面的两个子类Er ...

随机推荐

  1. grep命令及基本正则表达式

    grep命令是Linux系统中一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来. grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功 ...

  2. element-ui+vuex共享自定义方法进行表单验证 validator

    element-ui的官网上写的自定义表单验证,方法都是写在单vue文件中的,不容易共享.怎么使用vuex将方法共享出来,各个组件都能用呢? 如下是一个验证age的数据, rules:{ age:[{ ...

  3. 利用Service Fabric承载eShop On Containers

    从模块化到微服务化 从Pet Shop 到eShop on Container都是Microsoft在技术演进的路径上给开发者展示.Net的开发能力和架构能力的Sample工程,Petshop的时候更 ...

  4. Java贪吃蛇感想

    暑假敲代码的效率真的不高呀,一个这种小游戏从最开始构思到最后实施代码,从最开始的Demo版本到最后的第四版本,花了一个星期了.本想再更新一个版本,加入双人对战模式,还想写个AI版,可是我估计按照现在我 ...

  5. JAVA的命名方式 ,JAVA的第一个打印时间的程序

    本文内容来自:Java的命名方式 ,Java的第一个打印时间的程序 – Break易站 1. Java的命名方式 Java采用了一种全新的方法来避免上述所有问题·为了给一个类库生成不会与其他名字混淆的 ...

  6. MicroPython可视化编程开发板—TurnipBit自制MP3教程实例

    转载请以链接形式注明文章来源(MicroPythonQQ技术交流群:157816561,公众号:MicroPython玩家汇) 当前我们都生活在一个有声有色的社会当中,欣赏美丽的景色,享受动人的音乐, ...

  7. 总结基础OOP(面向对象)

    OOP其实也就是面向对象编程.  一:什么是对象:  我们最常见的理解方式无非是:对象(object)是任何看得见.摸得着.感觉得到,可以获得的东西,有自己的标识的任何东西.对象是某一类的事物的具体个 ...

  8. django之admin流程

    admin 类复习: class Base(object): def __init__(self,val): self.val = val def func(self): self.test() pr ...

  9. 从Unity中的Attribute到AOP(四)

    本篇我们将逐一讲解Unity中经常使用的Attribute(Unity对应的文档版本为2018.1b). 首先是Serializable,SerializeField以及NonSerialized,H ...

  10. 从头开始基于Maven搭建SpringMVC+Mybatis项目(1)

    技术发展日新月异,许多曾经拥有霸主地位的流行技术短短几年间已被新兴技术所取代. 在Java的世界中,框架之争可能比语言本身的改变更让人关注.近几年,SpringMVC凭借简单轻便.开发效率高.与spr ...