极客时间杨晓峰JAVA36讲内容总结与扩展(二)

Exception和Error有什么区别?

exception和error都继承了Throwable类,在java中只有Throwable类型的实例才能被捕获或者抛出,他是异常处理机制的基本组成类型。

Error是指正常情况下,不大可能出现的情况。大部分的Error会导致系统处于非正常状态、不可恢复状态。常见的有OutOfMemoryError等xxxError都是Error的子类。

Exception又分为可检查异常和不检查异常。可检查异常在源代码里必须显示的进行捕获处理。不检查异常就是所谓的运行时异常,NullPointerException等,这类不会再编译期强制要求。

Error、Exception、RuntimeException都有哪些?

21ab423c0b4f4e55ff15f23d86bef481ac6.jpg

Error相关

    1.AWTError:当发生严重的 Abstract Window Toolkit 错误时,抛出此错误。

    2.VirtualMachineError:抛出以表明Java虚拟机已损坏或已耗尽资源以使其继续运行。

        1>StackOverflowError:当堆栈溢出发生时抛出

        2>OutOfMemoryError:当Java虚拟机由于内存不足而无法分配对象时抛出,并且垃圾收集器不再有可用的内存

Exception相关

    1.IOException:表示发生某种类型的I / O异常。 此类是由失败或中断的I / O操作产生的一般异常类。

        1>EOFException:表示在输入过程中意外地到达文件结束或流结束。

        2>fileNotFoundException:指示尝试打开由指定路径名表示的文件失败

    2.RuntimeException:是在Java虚拟机的正常操作期间可以抛出的那些异常的超类
        1>ArithmeticException:抛出异常算术条件时抛出

        2>MissingResourceException:表示资源丢失

        3>ClassNotFoundException:没有找到具有指定名称的类的定义

        4>NullPointerException:空指针异常

        5>IllegalArgumentException:抛出表示一种方法已经通过了非法或不正确的参数

        6>ArrayIndexOutOfBoundsException:抛出以表示使用非法索引访问数组。 索引为负数或大于或等于数组的大小

下面举个例子看看有什么问题:

try{
     ....
     Thread.sleep(1000L);
   }catch(Exception e){
  
   }

第一:尽量不要捕获Exception这样的通用异常,需要根据代码去捕获特定异常,就如上代码所示应该捕获InterruptedException。

第二:catch代码块中异常生吞。并没有把异常抛出,如果真的出现问题不好判断从哪里排查。

try {
   // 业务代码
   // …
} catch (IOException e) {
    e.printStackTrace();
}

在生成过程中我们也是不允许这样去catch异常,因为什么呢?可以看看printStackTrace()的文档,“Prints this throwable and its backtrace to the standard error stream”。在复杂的生产系统中,标准出错不是个合适的输出选项,很难判断到底输出到哪里。

在分布式系统中如果发生异常,无法找到堆栈轨迹,那就是为诊断设置障碍。所以最好使用产品日志,详细的输出到日志系统。

throw early,catch later原则。

public void readPreferences(String fileName){
	 //...perform operations... 
	InputStream in = new FileInputStream(fileName);
	 //...read the preferences file...
}

如果fileName是null就会排除空指针异常。在实际代码中,可能是各种情况,例如获取配置失败等问题,如果第一时间抛出就能够更清晰的反应出问题。

对于下面的代码是对“throw early”的最好体现:

public void readPreferences(String filename) {
	Objects. requireNonNull(filename);
	//...perform other operations... 
	InputStream in = new FileInputStream(filename);
	 //...read the preferences file...
}
public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

至于“catch late”,其实是我们经常苦恼的问题。捕获异常后需要怎么处理,最差的方式就是生吞。如果实在不知道怎么去处理,可以保留异常信息,在更高层面往往更清楚合适的处理方式。

从性能的角度分析JAVA异常处理机制:

  • try-catch会有额外的性能开销,尽量不要把一个大的try包住一整段代码
  • Exception每实例化一个都会对当时的栈进行快照。如果发生频繁,那这个开销就不能被忽略
评论留言
adrian-jser:
假如你开车上山,车坏了,你拿出工具箱修一修,修好继续上路(Exception被捕获,从异常中恢复,继续程序的运行),车坏了,你不知道怎么修,打电话告诉修车行,告诉你是什么问题,要车行过来修。(在当前的逻辑背景下,你不知道是怎么样的处理逻辑,把异常抛出去到更高的业务层来处理)。你打电话的时候,要尽量具体,不能只说我车动不了了。那修车行很难定位你的问题。(要补货特定的异常,不能捕获类似Exception的通用异常)。还有一种情况是,你开车上山,山塌了,这你还能修吗?(Error:导致你的运行环境进入不正常的状态,很难恢复)

总结:

在没有学习这篇文之前,对于捕获异常和抛出异常这两个概念很模糊。只知道捕获用try-catch,抛出用Exception;而且有的时候觉得捕获异常很麻烦,就直接将整段代码放在了try中,这种方法很不可取,以后需要改正,我相信不光是我一个人是这样吧。

下面这张图是我聚XXX的领导发的朋友圈:

b5f566e9e744d453c551beb034011e5f5d7.jpg

希望大家能够知道异常的重要性。

转载于:https://my.oschina.net/Pirvate/blog/3020037

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值