Java中的异常 Exception

  java.lang.Exception类是Java中所有异常的直接或间接父类。即Exception类是所有异常的根类。

  比如程序:

  1. public class ExceptionTest
  2. {
  3. public static void main(String[] args)
  4. {
  5. int a = 3;
  6. int b = 0;
  7. int c = a / b;
  8. System.out.println(c);
  9. }
  10. }

 编译通过,执行时结果:

  Exception in thread "main" java.lang.ArithmeticException: / by zero

  at com.learnjava.exception.ExceptionTest.main(ExceptionTest.java:9)

  因为除数为0,所以引发了算数异常。

  比较常见的异常还有这种:空指针异常

  java.lang.NullPointerException是空指针异常,出现该异常的原因在于某个引用为null,但却调用了它的某个方法,这时就会出现该异常。

Java中的异常分为两大类:

  1.Checked Exception(非Runtime Exception

  2.Unchecked ExceptionRuntime Exception

运行时异常

  RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运行时异常都会直接或者间接地继承自RuntimeException类。

  Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时异常

异常处理的一般结构

 

  1. try
  2. {
  3. // 可能发生异常的代码
  4.   // 如果发生了异常,那么异常之后的代码都不会被执行
  5. }
  6. catch (Exception e)
  7. {
  8. // 异常处理代码
  9. }
  10. finally
  11. {
  12. // 不管有没有发生异常,finally语句块都会被执行
  13. }

比如本文最开始的除法运算代码,加入异常处理之后:

  1. public class ExceptionTest
  2. {
  3. public static void main(String[] args)
  4. {
  5. int c = 0;
  6. try
  7. {
  8. int a = 3;
  9. int b = 0;
  10.  
  11. // 这块代码出现了异常
  12. c = a / b;
  13.  
  14. // 那么异常之后的代码都不会被执行
  15. System.out.println("Hello World");
  16. }
  17. catch (ArithmeticException e)
  18. {
  19. e.printStackTrace();
  20. }
  21. finally
  22. {
  23. //不管有没有发生异常,finally语句块都会被执行
  24. System.out.println("Welcome");
  25. }
  26.  
  27. System.out.println(c);
  28. // 当b为0时,有异常,输出为c的初始值0
  29. }
  30. }

输出结果为

多个catch

  一个try后面可以跟多个catch,但不管多少个,最多只会有一个catch块被执行。

异常处理方法

  对于非运行时异常(checked exception),必须要对其进行处理,否则无法通过编译。

  处理方式有两种:

  1.使用try..catch..finally进行捕获;

  2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,将异常抛出到外面一层去。

  对非运行时异常的处理详见代码例子:

  处理方式1:将异常捕获

  1. 将异常捕获
  2.  
  3. public class ExceptionTest2
  4. {
  5. public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
  6. {
  7. System.out.println("Hello World");
  8.  
  9. // 抛出异常
  10. throw new Exception();
  11. }
  12.  
  13. public static void main(String[] args)
  14. {
  15. ExceptionTest2 test = new ExceptionTest2();
  16.  
  17. try
  18. {
  19. test.method();
  20. }
  21. catch (Exception e)
  22. {
  23. e.printStackTrace();
  24. }
  25. finally
  26. {
  27. System.out.println("Welcome");
  28. }
  29.  
  30. }
  31.  
  32. }

处理方式2:将异常继续向外抛出

  1. 将异常抛出
  2.  
  3. public class ExceptionTest2
  4. {
  5. public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
  6. {
  7. System.out.println("Hello World");
  8.  
  9. // 抛出异常
  10. throw new Exception();
  11. }
  12.  
  13. public static void main(String[] args) throws Exception // main方法选择将异常继续抛出
  14. {
  15. ExceptionTest2 test = new ExceptionTest2();
  16.  
  17. test.method(); // main方法需要对异常进行处理
  18.  
  19. // 执行结果:
  20. // Hello World
  21. // Exception in thread "main" java.lang.Exception
  22. // at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)
  23. // at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)
  24. }
  25.  
  26. }

对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。

自定义异常

  所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。

  通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。

  自定义异常可以用于处理用户登录错误,用户输入错误提示等。

  自定义异常的例子:

  自定义一个异常类型: 

  1. public class MyException extends Exception
  2. {
  3. public MyException()
  4. {
  5. super();
  6. }
  7. public MyException(String message)
  8. {
  9. super(message);
  10. }
  11. }

一种处理方式

  1. 一种异常处理方式
  2.  
  3. public class ExceptionTest4
  4. {
  5.  
  6. public void method(String str) throws MyException
  7. {
  8. if(null == str)
  9. {
  10. throw new MyException("传入的字符串参数不能为null!");
  11. }
  12. else
  13. {
  14. System.out.println(str);
  15. }
  16. }
  17.  
  18. public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出
  19. {
  20. ExceptionTest4 test = new ExceptionTest4();
  21. test.method(null);
  22. }
  23. }

另一种处理方式

  1. 异常处理方式二
  2.  
  3. public class ExceptionTest4
  4. {
  5.  
  6. public void method(String str) throws MyException
  7. {
  8. if (null == str)
  9. {
  10. throw new MyException("传入的字符串参数不能为null!");
  11. }
  12. else
  13. {
  14. System.out.println(str);
  15. }
  16. }
  17.  
  18. public static void main(String[] args)
  19. {
  20. //异常处理方式2,采用try...catch语句
  21. try
  22. {
  23. ExceptionTest4 test = new ExceptionTest4();
  24. test.method(null);
  25.  
  26. }
  27. catch (MyException e)
  28. {
  29. e.printStackTrace();
  30. }
  31. finally
  32. {
  33. System.out.println("程序处理完毕");
  34. }
  35.  
  36. }
  37. }

前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块

  下面这个例子,定义了两种自定义的异常类型:

  1. 多种异常
  2.  
  3. public class MyException extends Exception
  4. {
  5.  
  6. public MyException()
  7. {
  8. super();
  9. }
  10.  
  11. public MyException(String message)
  12. {
  13. super(message);
  14. }
  15. }
  16.  
  17. public class MyException2 extends Exception
  18. {
  19. public MyException2()
  20. {
  21. super();
  22. }
  23. public MyException2(String message)
  24. {
  25. super(message);
  26. }
  27.  
  28. }
  29.  
  30. public class ExceptionTest4
  31. {
  32.  
  33. public void method(String str) throws MyException, MyException2
  34. {
  35. if (null == str)
  36. {
  37. throw new MyException("传入的字符串参数不能为null!");
  38. }
  39. else if ("hello".equals(str))
  40. {
  41. throw new MyException2("传入的字符串不能为hello");
  42. }
  43. else
  44. {
  45. System.out.println(str);
  46. }
  47. }
  48.  
  49. public static void main(String[] args)
  50. {
  51. // 异常处理方式2,采用try...catch语句
  52. try
  53. {
  54. ExceptionTest4 test = new ExceptionTest4();
  55. test.method(null);
  56.  
  57. }
  58. catch (MyException e)
  59. {
  60. System.out.println("进入到MyException catch块");
  61. e.printStackTrace();
  62. }
  63. catch (MyException2 e)
  64. {
  65. System.out.println("进入到MyException2 catch块");
  66. e.printStackTrace();
  67. }
  68. finally
  69. {
  70. System.out.println("程序处理完毕");
  71. }
  72.  
  73. }
  74. }

我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。

  如果异常类型是独立的,那么它们的前后顺序没有要求。

  如对上面的代码进行改动后,如下列出:

  1. 多个catch语句块的顺序
  2.  
  3. public class ExceptionTest4
  4. {
  5.  
  6. public void method(String str) throws Exception // 也可以声明Exception,只要声明的可以涵盖所有抛出的异常即可
  7. {
  8. if (null == str)
  9. {
  10. throw new MyException("传入的字符串参数不能为null!");
  11. }
  12. else if ("hello".equals(str))
  13. {
  14. throw new MyException2("传入的字符串不能为hello");
  15. }
  16. else
  17. {
  18. System.out.println(str);
  19. }
  20. }
  21.  
  22. public static void main(String[] args)
  23. {
  24. // 异常处理方式2,采用try...catch语句
  25. try
  26. {
  27. ExceptionTest4 test = new ExceptionTest4();
  28. test.method(null);
  29.  
  30. }
  31. catch (MyException e)
  32. {
  33. System.out.println("进入到MyException catch块");
  34. e.printStackTrace();
  35. }
  36. catch (MyException2 e)
  37. {
  38. System.out.println("进入到MyException2 catch块");
  39. e.printStackTrace();
  40. }
  41. catch (Exception e)
  42. {
  43. //虽然需要加上,但是这块代码不会被执行,只是为了编译成功
  44. System.out.println("进入到MyException catch块");
  45. e.printStackTrace();
  46. //如果去掉前面两个catch块或其中之一,则发生该异常时就会进入此catch块
  47. //catch块的匹配是按照从上到下的顺序,所以这个块如果放在最前面就会捕获所有的异常,后面的块永远不会执行,这时候会提示编译错误
  48. }
  49. finally
  50. {
  51. System.out.println("程序处理完毕");
  52. }
  53.  
  54. }
  55. }

练习

  1. 笔试面试题解析
  2.  
  3. public class ExceptionTest5
  4. {
  5.  
  6. public void method()
  7. {
  8. try
  9. {
  10. System.out.println("进入到try块");
  11.  
  12. //return;
  13. //会先执行finally块再返回
  14.  
  15. //虚拟机退出
  16. //System.exit(0);
  17. //不会执行finally块中的语句,直接退出
  18. }
  19. catch (Exception e)
  20. {
  21. System.out.println("异常发生了!");
  22.  
  23. }
  24. finally
  25. {
  26. System.out.println("进入到finally块");
  27.  
  28. }
  29.  
  30. System.out.println("后续代码");
  31.  
  32. }
  33.  
  34. public static void main(String[] args)
  35. {
  36. ExceptionTest5 test = new ExceptionTest5();
  37. test.method();
  38. }
  39. }

在加上return语句前,程序输出:

    进入到try块

    进入到finally块

    后续代码

  如果在try块中加入return语句:

  程序执行输出:

    进入到try块

    进入到finally块

  说明try块中有return语句时,仍然会首先执行finally块中的语句,然后方法再返回。

  如果try块中存在System.exit(0);语句,那么就不会执行finally块中的代码,因为System.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行。

java——关于异常处理机制的简单原理和应用2(转)的更多相关文章

  1. java——关于异常处理机制的简单原理和应用

    异常处理机制的简单原理和应用 一.Execption可以分为java标准定义的异常和程序员自定义异常2种 (1)一种是当程序违反了java语规则的时候,JAVA虚拟机就会将发生的错误表示为一个异常.这 ...

  2. java中异常处理机制的简单原理

    以上是自认为的java异常处理的简单原理,如有不妥之处还请各位大神帮忙指点,谢谢!

  3. Java中的异常处理机制的简单原理和应用?

    程序运行过程中可能出现各种"非预期"情况,这些非预期情况可能导致程序非正常结束. 为了提高程序的健壮性,Java提供了异常处理机制: try { s1... s2... s3... ...

  4. Java中的异常处理机制的简单原理和应用

    异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间.地点.人物.情节等信息,可以用一个对象来表示,Java使用面向对象的方式 ...

  5. 【Java面试题】21 Java中的异常处理机制的简单原理和应用。

    异常指Java程序运行时(非编译)所发生的非正常情况或错误. java对异常进行了分类,不同类型的异常使用了不同的java类,所有异常的根类为java.lang.Throwable.Throwable ...

  6. JAVA异常处理机制的简单原理和应用

  7. 43 java中的异常处理机制的简单原理和应用

  8. 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)

    在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...

  9. Java垃圾回收机制的工作原理

    Java垃圾回收机制的工作原理 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 获取更多内容,请关注小编个人微信公众平台: 一.Java中引入垃圾回收机制的作用 ...

随机推荐

  1. MSSQL-SQL SERVER一些使用中的技巧

    获取前一天时间"getdate() - 1" 获取上一小时时间"dateadd(hour, -1, getdate())" order by field1, f ...

  2. html学习第一讲(内容html常规控件的的使用)

    <html> <head> <title> 这是网页的标题</title> </head> <body> <h2>& ...

  3. HDUOJ-----2852 KiKi's K-Number(树状数组+二分)

    KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  4. Java使用Selenium几个例子

    零.姿势 Selenium分为两个版本:Selenium RC和Selenium Webdriver.现在用Selenium Webdriver比较多. Selenium是一套工具,而不仅仅是一个操纵 ...

  5. 转:http协议学习

    协议详解篇 2.1 HTTP/1.0和HTTP/1.1的比较 RFC 1945定义了HTTP/1.0版本,RFC 2616定义了HTTP/1.1版本. 笔者在blog上提供了这两个RFC中文版的下载地 ...

  6. Linux内核中锁机制之完成量、互斥量

    在上一篇博文中笔者分析了关于信号量.读写信号量的使用及源码实现,接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题. 八.完成量 下面讨论完成量的内容,首先需明确完成量表示为一个执行单元需要等 ...

  7. Spring AOP声明式事务异常回滚(转)

    转:http://hi.baidu.com/iduany/item/20f8f8ed24e1dec5bbf37df7 Spring AOP声明式事务异常回滚 近日测试用例,发现这样一个现象:在业务代码 ...

  8. Java WebService 简单实例(转

    一.准备工作(以下为本实例使用工具) 1.MyEclipse10.7.1 2.JDK 1.6.0_22 二.创建服务端 1.创建[Web Service Project],命名为[TheService ...

  9. 如何安装rockmongo(gui for mongodb)

    1.下载rockmongo 下载地址: http://rockmongo.com/downloads 将下载下来的压缩包rockmongo-1.1.5.zip解压到web 发布目录(我这里使用的是ap ...

  10. 在Spring中注入Java集合

    集合注入重要是对数组.List.Set.map的注入,具体注入方法请参照一下代码(重点是applicationContext.xml中对这几个集合注入的方式): 1.在工程中新建一个Departmen ...