码迷,mamicode.com
首页 > 其他好文 > 详细

[02] 异常链和自定义异常

时间:2017-09-01 12:45:41      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:stat   种类   nts   weight   str   runtime   dex   native   sys   


1、异常链

1.1 throw

我们之前比喻过,说异常的抛出就像棒球中的投球,其中RuntimeException是发生意外后程序自行抛出的,假如我们想要自己抛出异常,就要使用 throw 关键字。
技术分享

显式地抛出异常通常写为:

  1. throw new xxxException();

异常抛出后,有两种处理方式:
  • 立即处理,使用 try catch 捕获并处理
  • 稍后处理,丢给方法调用的上层处理,使用 throws 关键字

  1. //try-catch 立即处理
  2. public static void fun() {
  3. File file = new File("C:/temp.txt");
  4. if (!file.exists()) {
  5. try {
  6. throw new IOException();
  7. } catch (IOException e) {
  8. System.out.println("文件不存在");
  9. }
  10. }
  11. }

  1. //throws 稍后处理
  2. public static void fun() throws IOException{
  3. File file = new File("C:/temp.txt");
  4. if (!file.exists()) {
  5. throw new IOException();
  6. }
  7. }

使用throw抛出异常时,不要直接使用Exception,或者相互之间有交集的异常,这样不能很好地标记异常的类型,增加了后期维护难度。


另外,在进行方法覆盖的时候要注意,假如你的某个方法覆盖了父类的某个方法,那么:
  • 不可以增加新的异常,即使这个新异常时父类方法声明中的任何一个异常的子类也不行
  • 不可以抛出 “被覆盖方法抛出异常” 的父类异常

例如:
  • 父类Animal方法fun()抛出两个异常:IndexOutOfBoundsException、IOException
  • 子类Cat覆盖方法fun()抛出异常最多两个,可以没有,同时子类抛出的异常,不能是父类抛出异常的父类,比如fun()不能抛出Exception(Exception是IndexOutOfBoundsException和IOException的父类)

可以这样理解:一个修理家电的人,他能够修理冰箱,电脑,洗衣机,电视机。 一个年轻人从他这里学的技术,就只能修理这些家电,或者更少。你不能要求他教出来的徒弟用从他这里学的技术去修理直升飞机。
技术分享

1.2 throws

如果抛出当前抛出的异常不希望立即处理,则可以在方法声明处使用throws关键字,指出方法引发的异常。可以声明多种异常类型,以逗号分隔开即可。
  1. public void test throws xxxException1, xxxException2, xxxException3 { ... }

技术分享
使用了throws的方法,被调用时就必须要求对其内的异常进行处理,同样,要么使用try-catch,要么继续使用throws往上抛,这种不断使用throws往上抛出异常直到被处理,就形成了一个所谓抽象的概念 “异常链”。

我们有时候在捕获一个异常后会抛出一个新的异常信息,并且希望将原始的异常信息也保存起来,这个时候也需要使用异常链。在Throwable及其子类中的构造器中都可以接受一个cause参数,该参数保存了原有的异常信息,通过getCause()就可以获取该原始异常信息。

  1. public class Test {
  2. public void f() throws MyException{
  3. try {
  4. FileReader reader = new FileReader("G:\\myfile\\struts.txt");
  5. Scanner in = new Scanner(reader);
  6. System.out.println(in.next());
  7. } catch (FileNotFoundException e) {
  8. //e 保存异常信息
  9. throw new MyException("文件没有找到--01", e);
  10. }
  11. }
  12. public void g() throws MyException{
  13. try {
  14. f();
  15. } catch (MyException e) {
  16. //e 保存异常信息
  17. throw new MyException("文件没有找到--02", e);
  18. }
  19. }
  20. public static void main(String[] args) {
  21. Test t = new Test();
  22. try {
  23. t.g();
  24. } catch (MyException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. }

  1. com.test9.MyException: 文件没有找到--02
  2. at com.test9.Test.g(Test.java:31)
  3. at com.test9.Test.main(Test.java:38)
  4. Caused by: com.test9.MyException: 文件没有找到--01
  5. at com.test9.Test.f(Test.java:22)
  6. at com.test9.Test.g(Test.java:28)
  7. ... 1 more
  8. Caused by: java.io.FileNotFoundException: G:\myfile\struts.txt (系统找不到指定的路径。)
  9. at java.io.FileInputStream.open(Native Method)
  10. at java.io.FileInputStream.<init>(FileInputStream.java:106)
  11. at java.io.FileInputStream.<init>(FileInputStream.java:66)
  12. at java.io.FileReader.<init>(FileReader.java:41)
  13. at com.test9.Test.f(Test.java:17)
  14. ... 2 more

如果在程序中,去掉e,也就是:throw new MyException("文件没有找到--02");  那么异常信息就保存不了,运行结果如下:
  1. com.test9.MyException: 文件没有找到--02
  2. at com.test9.Test.g(Test.java:31)
  3. at com.test9.Test.main(Test.java:38)


2、自定义异常

Java已经给我们提供了很多不同种类的异常,但是即使如此,也并不能预见所有的异常类型,特别是我们在业务上出现的错误。所以Java允许我们自定义异常,来表现程序中遇到的一些特殊问题。

我们自定义的异常类,主要还是用于标记业务逻辑的问题,避免与标准异常混淆。定义也很简单,只需要继承 Exception 即可

  1. public class MyException extends Exception {
  2. public MyException(String msg){
  3. super(msg);
  4. }
  5. }

自定义异常中往往不写其他的方法,只需要重载使用的构造方法。当然,也可以不写,使用默认的构造方法即可。

自定义异常往往是通过 throw 进行抛出使用。


3、参考链接


[02] 异常链和自定义异常

标签:stat   种类   nts   weight   str   runtime   dex   native   sys   

原文地址:http://www.cnblogs.com/deng-cc/p/7462493.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!