Java异常处理与详解问题合集

版权声明: https://blog.csdn.net/qq_41342776/article/details/80527939

Java异常处理与详解 

作者:华

日期:2018年5月30日

一次考试考到Java自定义异常,没有做出来,只是简单地了解了一下,为了巩固知识,就从各大网站总结了关于Java异常的处理解释来加深自己的印象。(全部文字虽有雷同但都是亲自手打无复制)


Java异常的意义:

异常就是可预测但是又没办法消除的一种错误。所以程序员为了在程序当中不发生这样的错误会将容易发生异常的代码用try catch进行处理,或者通过throws将异常向上抛出,由上一级进行接收并处理。如果发生异常而不去处理,会导致程序中断,也就是程序无法继续运行。


Java异常的分类和结构图:

Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。


扫描二维码关注公众号,回复: 3951931 查看本文章

Throwable又派生出Error类和Exception类。

Error:错误,错误代表JVM本身的错误。Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。

Exception:异常,java异常处理肯定就是异常才是主要要掌握的内容,代表程序运行时发送的各种不可期望的事件,可以被Java异常处理机制使用,表示程序本身处理的异常。


Javac将异常类分为两类,不检查异常和检查异常:

RuntimeException也称为unchecked exception(不检查异常),非RuntimeException也称为checked exception(检查异常),它们之间的区别可以望文生义。 RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws字句声明抛出它,还是会编译通过,这种异常可以通过改进代码实现来避免。

检查异常就是说程序中遇到这种异常的时候,程序需要对这种异常进行处理,检查异常的例子有:IOException, SQLException,ClassNotFoundException等等。对于检查异常,处理方式有三种:

1. 采用try...catch...finally

2. 直接throw给上层调用

3. 对该异常进行捕获,然后将它封装成自定义的Exception,然后再throw给上层调用。


Java异常处理机制:

对于可能可能出现异常的代码,有两种处理办法:

第一.  在方法中用try...catch语句捕获并处理异常,catach语句可以有多个,用来匹配多个异常。


InputStream是一个io异常,所以需要处理,可以用try{}(){}来处理,也可以抛出异常,现在来说说抛出异常throws。

第二. 对于处理不了的异常或者要转型的异常,在方法的声明处通过throws语句抛出异常。


可以看到处理Socket服务端的IO异常有两种方式,一种throws和try/catch。

 

处理后就将IOException抛出给下一个需要调用这个name1方法的方法。如果一直不调用最终会抛给Java虚拟机处理,所以不建议使用抛出异常。


从上面这张图片可以看出,如果方法name调用name1还是需要处理异常。

 

finally

finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。

良好的编程习惯是:在try块中打开资源,在finally块中清理释放这些资源。

需要注意的地方:

1、finally块没有处理异常的能力。处理异常的只能是catch块。

2、在同一try…catch…finally块中 ,如果try中抛出异常,且有匹配的catch块,则先执行catch块,再执行finally块。如果没有catch块匹配,则先执行finally,然后去外面的调用者中寻找合适的catch块。

3、在同一try…catch…finally块中 ,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去外围调用者中寻找合适的catch块。

下面用代码呈现出finally块的使用。



自定义异常:

如果要自定义异常,则扩展Exception即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。

 

按照国际惯例,自定义的异常应该总是包含如下的构造函数:

·        一个无参构造函数

·        一个带有String参数的构造函数,并传递给父类的构造函数。

·        一个带有String参数和Throwable参数,并都传递给父类构造函数

·        一个带有Throwable 参数的构造函数,并传递给父类的构造函数。

 

使用throw人为的让程序出异常(了解)



处理异常时注意事项:

1. 对于运行时异常(RuntimeException类及其子类都被称为运行时异常)我们不要用try...catch来捕获处理,而是在程序开发调试阶段,尽量去避免这种异常,一旦发现该异常,正确的做法就会改进程序设计的代码和实现方式,修改程序中的错误,从而避免这种异常。捕获并处理运行时异常是好的解决办法,因为可以通过改进代码实现来避免该种异常的发生。

2. (了解)异常的链化:

在一些大型的,模块化的软件开发中,一旦一个地方发生异常,则如骨牌效应一样,将导致一连串的异常。假设B模块完成自己的逻辑需要调用A模块的方法,如果A模块发生异常,则B也将不能完成而发生异常,但是B在抛出异常时,会将A的异常信息掩盖掉,这将使得异常的根源信息丢失。异常的链化可以将多个模块的异常串联起来,使得异常信息不会丢失。

异常链化:以一个异常对象为参数构造新的异常对象。新的异对象将包含先前异常的信息。这项技术主要是异常类的一个带Throwable参数的函数来实现的。这个当做参数的异常,我们叫他根源异常(cause)。在JDK1.4以后版本中,Throwable类支持异常链机制。Throwable 包含了其线程创建时线程执行堆栈的快照。它还包含了给出有关错误更多信息的消息字符串。最后,它还可以包含 cause(原因):另一个导致此 throwable 抛出的 throwable。它也称为异常链 设施,因为 cause 自身也会有 cause,依此类推,就形成了异常链,每个异常都是由另一个异常引起的。 
        通俗的说,异常链就是把原始的异常包装为新的异常类,并在新的异常类中封装了原始异常类,这样做的目的在于找到异常的根本原因。
        通过Throwable的两个构造方法可以创建自定义的包含异常原因的异常类型:
Throwable(String message, Throwable cause) 
         构造一个带指定详细消息和 cause 的新 throwable。 
Throwable(Throwable cause)
 
         构造一个带指定cause 和 (cause==null ? null :cause.toString())(它通常包含类和 cause 的详细消息)的详细消息的新 throwable。 
getCause()
 
         返回此throwable 的 cause;如果 cause 不存在或未知,则返回 null。
initCause(Throwable cause) 
         将此throwable 的 cause 初始化为指定值。

        在Throwable的子类Exception中,也有类似的指定异常原因的构造方法:
Exception(String message, Throwable cause) 
         构造带指定详细消息和原因的新异常。 
Exception(Throwable cause)
 
         根据指定的原因和 (cause==null ? null : cause.toString()) 的详细消息构造新异常(它通常包含 cause 的类和详细消息)。 
因此,可以通过扩展Exception类来构造带有异常原因的新的异常类。

3. 避免过大的try块,不要把不会出现异常的代码放到try块里面,尽量保持一个try块对应一个或多个异常。

4.细化异常的类型,不要不管什么类型的异常都写成Excetpion
5.catch
块尽量保持一个块捕获一类异常,不要忽略捕获的异常,捕获到后要么处理,要么转译,要么重新抛出新类型的异常。

6.不要把自己能处理的异常抛给别人。

7.不要用try...catch参与控制程序流程,异常控制的根本目的是处理程序的非正常情况。

8.当子类重写父类的带有 throws声明的函数时,其throws声明的异常必须在父类异常的可控范围内——用于处理父类的throws方法的异常处理器,必须也适用于子类的这个带throws方法 。这是为了支持多态。

9.对于finally语句块

·        不要在fianlly中使用return。

·        不要在finally中抛出异常。

·        减轻finally的任务,不要在finally中做一些其它的事情,finally块仅仅用来释放资源是最合适的。

·        将尽量将所有的return写在函数的最后面,而不是try … catch … finally中。

 

Java 根据各个类库也定义了一些其他的异常,下面的表中列出了 Java 的非检查性异常。

下面的表中列出了 Java 定义在 java.lang 包中的检查性异常类

 

这里有六道关于Java异常的面试题

https://www.cnblogs.com/gaoweixiao99/p/4905860.html

参考资料:http://blessht.iteye.com/blog/908286http://www.oschina.net/translate/10-exception-handling-best-practices-in-java-programming

http://blog.csdn.net/snow_fox_yaya/article/details/1823205

http://www.iteye.com/topic/72170

http://www.blogjava.net/gdws/archive/2010/04/25/319342.html

http://www.2cto.com/kf/201403/284166.html

http://www.iteye.com/topic/857443

http://developer.51cto.com/art/200808/85625.htm

http://www.cnblogs.com/JavaVillage/articles/384483.html

http://tech.e800.com.cn/articles/2009/79/1247105040929_1.html

http://blog.csdn.net/zhouyong80/article/details/1907799

http://blog.csdn.net/luoweifu/article/details/10721543  

猜你喜欢

转载自blog.csdn.net/qq_41342776/article/details/80527939