这篇和前面的 总结java的interface和abstract class 一样。跳过最基础语法不聊,只说一些比较tricky的东西和一些好的practice.

语法:

Exception继承自Throwable. Throwable还有一个儿子是Error,但是一般用不到。不过有些二百五面试官喜欢问回字有几种写法,所以还是要知道有Error这回事的。Exception分为checked和unchecked两种。

java的checked exception一直是个很有争议的东西。Thinking in Java的作者Bruce, C#的设计者和Martin Fowler都对checked exception持质疑态度。 一个典型的反对理由是:"We felt it was unrealistic to require the programmer to provide handlers in situations where no meaningful action can be taken." 这话太实惠了。写方法给caller调用,怎么能magically知道调用这个方法的所有caller,能够处理特定的异常呢?

关于Exception有个比较基本的语法是,子类override的方法如果声明抛出exception, 只能抛出父方法声明的exception,或者那个exception的子类。需要注意的是,“回”字还有一种写法,对于constructor来说没有这个限制,子类可以抛出任意exception。父类构造函数声明的exception,子类也必须声明,而且子类的构造函数不能捕捉父类声明的exception. 这个想想也容易理解,父类构造出错了,儿子居然能处理还把自己生出来了,没老子哪来的儿子?当然你可以抬杠说老子戴绿帽子的情况。

实践:

1. 尽量不要在构造函数里做复杂的操作,尽量不要让constructor抛出exception。如果在构造函数里抛出exception,需要用nested try block. 如下:

1: public class Cleanup {

2: public static void main(String[] args) {

3: try {

4: InputFile in = new InputFile("Cleanup.java");

5: try {

6: String s;

7: int i = 1;

8: while((s = in.getLine()) != null)

9: ; // Perform line-by-line processing here...

10: } catch(Exception e) {

11: System.out.println("Caught Exception in main");

12: e.printStackTrace(System.out);

13: } finally {

14: in.dispose();

15: }

16: } catch(Exception e) {

17: System.out.println("InputFile construction failed");

18: }

19: }

20: }

而不是用finally来做清理工作。

2. exception的一个基本使用原则是,exception不是设计用来控制程序flow的。 这是很简单的道理,还是引用effective java的一个例子吧

1: // Horrible abuse of exceptions. Don't ever do this!

2: try {

3: int i = 0;

4: while(true)

5: range[i++].climb();

6: } catch(ArrayIndexOutOfBoundsException e) {

7: }

我真正要说明的是,上面说的原则很对,但是走到极端就不对了。有的人为了 不用exception控制程序flow, 就写一大堆的if…else语句试图考虑各种情况,正好前不久有同事说了个笑话,我觉得可以辅助解释这个问题。

=============================

某日,老师在课堂上想考考学生们的智商,就问一个男孩“树上有十只鸟,开枪打死一只,还剩几只?”

男孩反问“是无声手枪,还是其他没有声音的枪么?”

“不是。”

“枪声有多大?”

“80~100分贝。”

“那就是说会震的耳朵疼?”

“是。”

“在这个城市里打鸟犯不犯法?”

“不犯。”

“您确定那只鸟真的被打死啦?”

“确定.”老师已经不耐烦了,”拜托,你告诉我还剩几只就行了,OK?”

“OK.鸟里有没有聋子?”

“没有。”

“有没有鸟智力有问题,呆傻到听到枪响不知道飞的?”

“没有,智商都在200以上!”

“有没有关在笼子里的?”

“没有。”

。。。

==============================

后面还有一堆“例外”情况。我们写程序总不能真写成

if(鸟是聋子)

else if(鸟是傻子)

else if(鸟是瘸子)

原则应该是,如果一些情况确实是 “例外情况”,就用exception处理吧。不要很勤奋地写一堆defensive的判断。我们不会有故事里的小男孩儿思维那么滴水不漏的。别把Java程序退回c语言了。另一个例子是FileNotFoundException, java I/O没有让你每次用文件都提前调用exists()检查一下,我想原因不光是 检查文件的那一毫秒文件存在,run到下一步的时候,下一毫秒文件消失了,Sun没觉得你人品那么坏吧。理念仍然是,如果你觉得文件肯定存在,你就直接用吧,一旦不存在,你再另外当成异常情况处理。不要让一堆if…else弄脏了程序。

3. exception有个典型用法是在方法体中,进行参数合法性校验

1: public BigInteger mod(BigInteger m) {

2: if (m.signum() <= 0)

3: throw new ArithmeticException("Modulus <= 0: " + m);

4: ... // Do the computation

5: }

也有很多人用assert语句判断, 比如 Assert.notNull(object)。手动抛exception可以抛特定的类型,assert语句更方便。可以根据实际情况取舍。

4. 既然上面说了checked exception本身是java设计不太合理的地方。我倾向于说,应该及时把checked exception translate成unchecked. 我知道exception的处理原则有一条是,如果你不知道怎么处理它,就不要捕捉它。 对于checked exception来说,它总force你去处理,太讨厌了。如果caller不知道怎么处理,留着给更上层的程序处理…底层的程序都不会处理,一般来说上层的程序就更不知道该怎么处理了,那还不如在尽量底层的调用中,要么处理它(这种情况很少,打log之类的算不上“处理”),要么就转成RuntimeException抛上来, 消灭掉checked exception带来的burden. 注意:translate exception的过程中,不要扔了原来的exception, 而要把它放在exception constructor的argument里, new RuntimeException(e)。这是很基本的东西,不多说。

5. 不要吞exception. 这个太基础,不多说。

6. 见到exception要把它记log里,而不是简单print stack一下,log4j的api有可以接受Throwable作为参数的。

7. 每层抛出来的exception要对当前这一层有意义,比如persistence层出问题,UI上你告诉客户hibernate的session关闭了,不能继续load数据了,客户还以为你的程序怎么跟狗熊一样还会冬眠的。即使是UI层以下,底层exception,比如sql exception也不要爬到domain层里处理

8. apache commons的lang包里有ExceptionUtils类,玩儿exception最好把这个工具揣口袋里。

9.exception是设计的一部分, 但它不同于API的设计。通常我们设计API的时候,不会设计一个函数destroyBaghdad(),通常我们会写destroyCity(Baghdad)。这样做的目的是为了重用。换句话说,你设计API的时候,总是装作忘了use case(caller),而去写适合复用的API, 尽管上面的例子use case就是destroy Baghdad, 你还是要写更general的destroyCity函数,然后把城市的名字作为参数传进去.但exception的设计不应该用同样的思路做,因为你很难料想到复用的情况下,你声明的exception是不是总能在任何情况下都得到妥善的处理。举个例子,这是我临时想的例子,形象但是科技太超前了。我们写一个print()程序给打印机A,print()的时候没有纸可以抛一个checked NoPaperException,这时候exceptino的处理程序可以自动加载纸(目前这么高级的功能正在贝尔实验室研发呢)。也许有新型的打印机B总是先加纸,后打印,那么永远也不存在NoPaperException。如果打印机是老式打印机C,不会自动加载纸,见到NoPaterException也无计可施,没法处理。checked exception的哲学是,强制让caller处理它。从上面的例子看,只有A打印机需要并能够处理NoPaperException。 B打印机不需要处理exception。C打印机没能力处理exception. 所以,|“需要并能够”处理是个太严格的限制,一般情况下不应该用checked exception. 我们可以让print声明抛出unchecked exception. 提醒caller可以处理它,但是对于不应该处理它的caller也不强制去处理它。

exception java_总结java的exception相关推荐

  1. java.sql.Exception:setString 只能处理少于 32766 个字符的字符串

    java.sql.Exception:setString 只能处理少于 32766 个字符的字符串 解决方式是 : 升级ojdbc的版本,   将原来的 ojdbc14_10.2.0.2.0.jar ...

  2. java.lang.exception_java.lang.RuntimeException和java.lang.Exception

    在查看java.lang.RuntimeException和java.lang.Exception类之间的区别之前,您必须知道Exception层次结构.两个类Exception和Error类都派生自 ...

  3. java中exception in_java.lang.ExceptionInInitializerError

    一.错误,原因 java.lang.ExceptionInInitializerError 二.原因 引起java.lang.ExceptionInInitializerError 错误的原因是:在类 ...

  4. Java继承Exception自定义异常类教程以及Javaweb中用Filter拦截并处理异常

    Java继承Exception自定义异常类教程以及Javaweb中用Filter拦截并处理异常 参考文章: (1)Java继承Exception自定义异常类教程以及Javaweb中用Filter拦截并 ...

  5. tomcat启动不了,报java.lang.Exception: Socket bind failed: [730013] ???

    今天突然发现TOMCAT6无法正常启动,报错误: 严重: Error starting endpoint java.lang.Exception: Socket bind failed: [73001 ...

  6. Java自定义Exception

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...

  7. java.lang.Exception: Socket bind failed: [730048]

    启动tomcat是遇到java.lang.Exception: Socket bind failed: [730048]. 打开任务管理器,找到javaw.exe,结束进程,启动tomcat成功.

  8. java经常会出现异常的是,“Java异常Exception”总结

    1. 异常(Exception). 2.Java中的异常分为两大类: a) Checked exception  (非  Runtime Exception) 非运行时异常 b) Unchecked ...

  9. JDK源码解析之 java.lang.Exception

    异常.是所有异常的基类,用于标识一般的程序运行问题.这些问题通常描述一些会被应用程序捕获的反常情况. 一.源码部分 //继承了java.lang.Throwable public class Exce ...

最新文章

  1. hadoop 第一课 启动dfs 文件系统
  2. 拉力赛 (Standard IO)
  3. 1.2 Java系统流
  4. centos7.3安装tomcat报Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
  5. python笔试题(1)
  6. 工作309:uni-获取vuex里面的值
  7. “Lephone.Data.DbEntry”的类型初始值设定项引发异常。(DbEntry.net3.9)
  8. Java实训项目9:GUI学生信息管理系统 - 实现步骤 - 创建数据访问接口
  9. Mac给Sublime Text 配置Python3开发环境
  10. 深入理解JVM之对象分配流程
  11. (CVPR2020 Oral)用于实时实例分割的Deep Snake方法
  12. 娜璋初识(一)你的酒窝没有酒,我却醉得像条狗,看程序员如何表白
  13. Lightly:新一代的C语言IDE
  14. fedora14 官方下载地址
  15. FastDB简单介绍及实例(Linux)
  16. 阿里天池—2022江苏气象预测AI算法挑战赛
  17. Springboot毕业设计管理系统
  18. 微信公众平台——用户管理
  19. 串口设备短信模块开发笔记
  20. ISP PIPLINE (二) LensShading Correct

热门文章

  1. linux怎么越狱苹果手机,苹果手机能不能安装deb?苹果手机越狱后怎么安装deb文件...
  2. 阿里云全站加速在游戏行业的最佳实践
  3. hz什么梗_90hz屏幕什么意思
  4. 深圳监控安装上门服务简介
  5. 【车间调度】FJSP的属性模型符号约定和约束条件
  6. 低配置系统安装 linux,在低配置机中安装Linux系统
  7. 干果进口关税是多少天津食品进口应办理哪些手续?
  8. html高德地图调用,插件的使用-入门-教程-地图 JS API | 高德地图API
  9. 与java比较_C++与Java比较
  10. (近5w字)面向小白のVue全家桶开发电商管理系统项目总结文档