Java异常

1.异常类型

1)Throwable 是所有异常的父类,它有两个直接子类 Error 和 Exception。

2)Error 表示系统级的错误,是 java 运行环境内部错误或者硬件问题,不能指望程序来处理这样的问题,除了退出运行外别无选择,它是 java 虚拟机抛出的。

     Exception 表示程序需要捕捉、需要处理的异常,是由与程序设计的不完善而出现的问题,程序可以处理的问题。

3)Exception 又被继续划分为被检查的异常(checked exception)和运行时的异常(runtime exception);

2.被检查的异常和不受检查的异常有什么区别?

1)被检查的异常应该用 try-catch 块代码处理或用 throws 关键字抛出,不受检查的异常在程序中不要求被处理或用 throws 抛出;

2)Exception 是所有被检查异常的基类,而 RuntimeException是所有不受检查异常的基类;

3. throw 与 throws 的区别

1)throw 使用的位置在方法中,后面跟的异常对象实例,表示抛出异常,由方法体内语句处理;throws 使用的位置在方法参数小括号后面,后面跟的是一个或者多个异常类名且用逗号隔开,表示抛出异常并交给调用者去处理

2)如果方法中有 throw 抛出 RuntimeException 及其子类则声明上可以没有 throws,如果方法中有 throw 抛出 Exception 及其子类则声明上必须有 throws。

3)如果throws 后面是 RuntimeException 及其子类则该方法可以不用处理,如果后面根据的是 Exception 及其子类则必须要编写代码进行处理或者调用的时候抛出。

4.异常链

异常链是指在进行一个异常处理时抛出了另外一个异常,由此产生了一个异常链条,大多用于将受检查异常(checked exception)封装成为非受检查异常(unchecked exception)或者 RuntimeException。特别注意如果你因为一个异常而决定抛出另一个新的异常时一定要包含原有的异常,这样处理程序才可以通过 getCause() 和 initCause() 方法来访问异常最终的根源。

5.java 中如何编写自定义异常

可以通过继承 Exception 类或其任何子类来实现自己的自定义异常类,自定义异常类可以有自己的变量和方法来传递错误代码或其它异常相关信息来处理异常。

6.程序代码陷阱 

1.ry-catch-finally 块

test1 方法运行返回 0,因为执行到 try 的 return ret; 语句前会先将返回值 ret 保存在一个临时变量中,然后才执行 finally 语句,最后 try 再返回那个临时变量,finally 中对 ret 的修改不会被返回。

test2 方法运行返回 2,因为 5/0 会触发 ArithmeticException 异常,但是 finally 中有 return 语句,finally 中 return 不仅会覆盖 try 和 catch 内的返回值且还会掩盖 try 和 catch 内的异常,就像异常没有发生一样(特别注意,当 finally 中没有 return 时该方法运行会抛出 ArithmeticException 异常)

test3 方法运行抛出 hello 异常,因为如果 finally 中抛出了异常,则原异常就会被掩盖。

2.异常类型优先级

因为 Exception 是 RuntimeException 的超类,func 方法执行的异常都会被第一个 catch 块捕获,所以会报编译时错误。

因为在 java 中重写方法抛出的异常不能是原方法抛出异常的父类,这里 func 方法在父类中抛出了 IOException,所有在子类中的 func 方法只能抛出 IOExcepition 或是其子类,但不能是其父类。

 

因为 IOException 是受检查异常,而 func 方法并没有抛出 IOException,所以编译报错。但是如果将 IOException 改为 Exception(或者 运行时异常 等)则编译报错将消失。

通过上面几个代码片段可以总结以下几点:

1)在书写多 catch 块时要保证异常类型的优先级书写顺序,要保证子类靠前父类靠后的原则;

2)在 java 中重写方法抛出的异常不能是原方法抛出异常的父类;

3)如果方法没有抛出受检查类型异常则在调用方法的地方就不能主动添加受检查类型异常捕获,但是可以添加运行时异常或者 Exception 捕获。

原文地址:https://www.cnblogs.com/mcahkf/p/9056206.html