龙空技术网

聊一聊java中的异常

妖精的杂七杂八 105

前言:

今天兄弟们对“java的异常类型可以分为两类”大致比较注意,咱们都需要剖析一些“java的异常类型可以分为两类”的相关内容。那么小编也在网上收集了一些有关“java的异常类型可以分为两类””的相关文章,希望咱们能喜欢,我们一起来学习一下吧!

异常是什么,有什么用

异常处理,顾名思义,就是当程序出现异常时候加以处理,使程序能够正确稳当的持续运行下去。

异常的分类

在java中,主要可以分为两类

ExcetionError

两者均继承自Throwable类,且只有继承自该类的类才能使用throw关键字抛出或使用try...cache...finally..进行捕获,而对于两者的区别(主要是两者设计上的区别)如下

Excetion侧重于持续运行中可以预料到的异常情况,如NullPointExcetion(空指针异常)、ArrayIndexOfBoundExcetion(数组越界)等Error侧重与在正常情况下不会出现的一些错误,当出现Error时,一般会导致持续非正常且不可修复。如OutOfMemoryError(内存溢出错误)、NoClassDefError(类无法连接)等。

Error与Excetion继承关系图

异常一定要抛出或捕获处理吗?

对于异常Excetion而言,其也可依照是否需要捕获分类两类,即

可检查异常(check)

持续在运行中可能出现异常时候必须使用throw关键字抛出或使用try..cache..finally语句加以处理,若不处理,在持续编译时就无法通过编译,常见的IoException就是check类型的异常。

不检查异常(uncheck)

持续在运行时候虽然可能出现异常,但是持续编写者可以对异常进行加以处理,也可以不处理异常(当异常出现时,在异常中打印堆栈),常见的NullPointExcetion、RuntimeExcetion就属于uncheck类型的异常。

异常的坑

equals的坑假如有这样一段程序private final String param="param" boolean equal(String str){ return str.equals(param) } 复制代码该程序在日常运行中是非常可能出现空指针异常的,因为我们无法限定参数传入是否为空,因此,在对一个变量和一个常量需要判断是否相等时,尽量调用常量的equals方法比较变量,防止出现可能的空指针异常(return param.equals(str))。类中的Boolean

日常程序中,使用if来做判断是必不可少的,而对于一个实体类而言,我们也通常需要使用if来判断实体类的状态。对于基本类型boolean而言,其默认值为false,而对于包装类Boolean来说,就为空了,若有这样一个实体类

class Entity{ Boolean state}String getStateStr(Entity e){if(e.state){return "ok"}else{return "no"}}

对于这段程序来说,也可能会出现空指针异常,尤其是在使用远程调用继续类包装时,我们无法判断传入的e为空还是e.state为空,因此,使用包装类时,尽量打印日志方便排查

已经继续了异常处理,但是在finally中也放了返回值,结果返回值不符合预期

try{ ..... return a;}cache(Excetion e){..... return b;}finally{.....return c;}

对于上述代码,在出现异常与不出现异常时的返回值会是什么呢?答案居然是c。

finally java中程序一定会执行的一种机制(当然特殊情况下也不一定执行,这里挖个坑),因此,无论是try中的返回值还是cache中的返回值,都是在程序运行时会将返回值压栈,当执行完finally的代码后,若finally中有返回值,即返回finally中的返回值,否则,返回栈中的返回值。

finally为什么不一定 一定执行

这句话是有点绕啊,其实就是围绕finally是不会一定执行这个问题来展开的,为什么呢?看下面一段程序

try{System.exit(0);}cache(Excetion e){.....}finally{    .....}

这是一种特殊情况,即把程序关掉来,那么程序还怎么执行呢?

异常也需要考虑性能

这是一个很关键的问题,对于小公司来说,我们往往可以牺牲一些性能来换取编程上的遍历,而对于超大形分布式系统而言,往往一点的性能差距就会有一只蝴蝶煽动翅膀卷起一阵龙卷风的效果,当然,我们并不希望出现龙卷风。当程序中出现出现异常时,每实例化一个异常,就会得到当前堆栈的快照,如

Exception in thread "main" java.lang.NullPointerException	at com.example.demo.DemoApplication.test(DemoApplication.java:16)	at com.example.demo.DemoApplication.main(DemoApplication.java:13)

日常的生产环境并不会向我给出得到的这么简单,少少2曾,通常往往是10+的,打印堆栈,对于JVM来说就是一笔较大的性能开销,所以,在日常编程中,往往要遵循最小原则,只对必要代码块进行异常捕获,并假如条件判断流程(if else\ switch ....)加以辅助,如空指针异常的处理就可以使用if来辅助判断,而不是使用NullPointExcetion进行捕获,减少性能开销。

总结

异常在java中的定义就是在程序运行中出现错误时,程序设计者对异常情况总结加以处理使程序能恢复到正常的运行中。异常的分类可以分为Error(错误)通常是系统级别的错误,出现该类型的异常即代表系统已经无法正常运行类、Excetion(异常)即系统运行时可能出现的问题,程序编写者加以处理即可使系统继续稳健运行下去,同时在日常编程中也应该不只关心check类型的异常,同时还应该去关注uncheck类型的异常,毕竟check类型的异常在程序编译后就已经有了处理方法类,而uncheck类型的异常在程序运行后可能出现,当出现又没有加以处理时,这时候也可以认为错误已经无法稳健运行了(Error),最后,就是还需要平衡好异常与性能之间的矛盾.

作者:WidenXu

链接:

标签: #java的异常类型可以分为两类 #java写一个异常