前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 异常处理机制

Java 异常处理机制

作者头像
王小明_HIT
发布2020-07-01 14:56:21
5070
发布2020-07-01 14:56:21
举报
文章被收录于专栏:程序员奇点程序员奇点

Java 异常处理机制

Exception 和 Error 有什么区别?

Exception 和Error 都是继承 Throwable 类,在 java 只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。Exception 和 Error 提现了 Java 平台设计者不同异常情况的类,Exception 在程序运行中,可预料的意外情况,并且可能被捕获,进行相应处理。

  • Error 是指在正常情况下,不大可能出现的情况,可能是因为JVM自身导致的,非正常情况,不便于捕获,常见的比如 OutOfMemorryError 之类的,都是Error 的子类。
  • Exception 又分为可检测异常(checked)和不检查异常(unchecked),可检查异常在源代码里必须显示的进行捕获处理。

Exception 可检测异常和不检查异常有哪些?

  • 不可检测异常(RunntimeException):NullPointerException、ClasCastException、ArrayIndexOutOfBoundsException ;
  • 检查异常: 如 IO 错误导致的 IOException 、SQLException。

image

异常处理的基本原则

尽量不要捕获类似 Exception 这样的通用异常

代码语言:javascript
复制
try {
    // 业务代码
    // …
    Thread.sleep(1000L);
} catch (Exception e) {
    // Ignore it
}

上面的代码有什么问题?

根据异常处理的基本原则,不要使用 Exception 这样的通用异常,需要捕获特点异常,上面的代码 Thread.sleep 会抛出 InterruptedException 应该捕获这个异常,软件工程师需要协作的,程序员有义务让代码能够直观体现出更多的信息。

其次不要生吞了异常,不能 ingonore ,当不需要抛出异常时,需要打印出相关异常信息。否则程序很可能以不可控的方式结束,不能够判断是哪里出现了异常。

不要生吞异常,(就是不要基于假设这段代码可能不会发生,或者感觉异常无所谓)如果这样很可能会导致非常难以诊断的诡异异常。

代码语言:javascript
复制
try {
    // 业务代码
    // …
} catch (IOException e) {
    e.printStackTrace();
}
  • https://docs.oracle.com/javase/9/docs/api/java/lang/Throwable.html#printStackTrace-- 生吞异常是指不把异常抛处理,也不输出日志Logger.这样很难定位是什么原因产生了异常。

“ Prints this throwable and its backtrace to the standard error stream ” 上面的代码可能出现的问题时,当系统复杂是,无法找到堆栈轨迹,不知道日志输出到哪了。

throw early ,catch late 原则

代码语言:javascript
复制
public void readPreferences(String fleName){
    //...perform operations...
    InputStream in = new FileInputStream(fleName);
    //...read the preferences fle...
}

比如说当从输入参数 filename 为null 时,程序就会抛出 NullPointerException ,但是由于没有爆出这个问题,堆栈信息可能让人费解,要做到的是就是在发现问题的时候,第一时间抛出,能够更清晰的反应问题。这个就是 throw early。这样,根据 throw early 就可以将代码改造如下:

代码语言:javascript
复制
public void readPreferences(String flename) {
    Objects. requireNonNull(flename);
    //...perform other operations...
    InputStream in = new FileInputStream(flename);
    //...read the preferences fle...
}

catch late

捕获异常后,要怎么处理,要么生吞异常。要么可以选择保留异常的cause 信息,直接再抛出去或者创建新的异常,抛出去,这样更高层面,往往可以更清楚处理方式是什么。

如何自定义异常

  • 是否需要定义成 Checked Exception ,因为这种类型设计是为了从异常中恢复出来
  • 保证诊断信息足够的同时,也要考虑包含敏感信息,因为那样可能存在安全问题,比如包含机器 IP 端口,用户数据等,一定要小心,不要输出到日志。

参考资料

  • https://www.journaldev.com/1696/exception-handling-in-java
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java 异常处理机制
    • Exception 和 Error 有什么区别?
      • Exception 可检测异常和不检查异常有哪些?
        • 异常处理的基本原则
          • 尽量不要捕获类似 Exception 这样的通用异常
          • 不要生吞异常,(就是不要基于假设这段代码可能不会发生,或者感觉异常无所谓)如果这样很可能会导致非常难以诊断的诡异异常。
          • throw early ,catch late 原则
        • 如何自定义异常
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档