java异常与错误处理

一、什么是异常

1.异常的概念

所谓异常就是没有达到程序预期的结果。

2.异常与错误

java中的异常与错误

  • 错误:虚拟机等相关的错误,开发人员无法在程序中做预处理
  • 异常:开发人员可以根据不同的异常类型设定一些处理方案
3.java中的异常体系

java中的异常类体系

  • Error : 错误类
  • Exception : 异常类(开发中重点关注的地方)

二、Java异常处理机制

1.异常捕获及处理
  • try : 表示可能出现问题的代码块,也是被捕获的代码段(不可能出现异常的代码块不建议放于其中)
  • catch : 当遇到对应的异常时,进行处理的代码块(可以针对不同的异常进行不同的处理或相同的处理)
  • finally : 无论是否出现异常,最终都会执行的代码块,一般用于释放资源,关闭连接、最终清理工作等
(1)不同类型的异常进行相应的捕获处理
  1. try {
  2. //可能出现错误的代码块
  3. } catch (ArrayIndexOutOfBoundsException ex) {
  4. //出现ArrayIndexOutOfBoundsException异常时的处理
  5. } catch (Exception ex) {
  6. //其他非ArrayIndexOutOfBoundsException异常时的处理
  7. } finally {
  8. //无论是否出现异常,最终都会执行的代码块
  9. }
(2)多个异常使用相同的处理:多个异常类型使用 | 隔开
  1. try {
  2. //可能出现问题的代码块
  3. } catch (ArrayIndexOutOfBoundsException | IOException e) {
  4. //同时捕获多个类型的异常,进行相同的处理
  5. }
(3)捕获异常时同时需要记录异常
  • 日志方式:在测试或开发环境追踪问题的根据
  • 控制台输出:一般在开发环境中使用

注:在记录的时候,最好有详细的上下文说明,并使用异常对象的printStackTrace()方法记录异常的调用栈链

2.断言

断言只是一种检测是否达到预期结果的判断的方式,并不参与异常处理,一般用于参数判断和单元测试等(断言默认是不开启的,可以通过修改JVM参数来开启:-ea或-enableassertions)

  • assert boolean表达式
  • assert boolean表达式 : 错误提示

注:使用assert关键词的结果:

  • 表达式为true:即通过,不做任何处理
  • 表达式为false:即未通过,会抛出一个AssertionError
  1. /**
  2. * 使用默认的会抛出AssertionError
  3. */
  4. public static void defaultDemo() {
  5. try {
  6. int a = 10;
  7. assert (a == 11);
  8. } catch (Throwable e) {
  9. e.printStackTrace();
  10. }
  11. }
  12. /**
  13. * 使用默认的会抛出AssertionError,并返回我们设置的错误提示信息
  14. */
  15. public static void useMessage() {
  16. try {
  17. int a = 10;
  18. assert (a == 11) : "不出false";
  19. } catch (Throwable e) {
  20. e.printStackTrace();
  21. }
  22. }

三、自定义异常

  • 1.自定义异常一般继承自Exception或RuntimeException
    • 可查的异常一般继承自Exception
    • 不可查的异常一般继承自RuntimeException
  • 2.建议有以下构造方法
    • (1)无参的构造方法
    • (2)接收一个异常提示参数的构造方法
    • (3)接收一个Exception或Exception子类对象的构造方法
    • (4)接收一个异常提示参数和一个Exception对象参数的构造方法
  1. /**
  2. * 自定义异常
  3. * @author shixinke
  4. * @date 2019-01-14
  5. */
  6. public class MyException extends Exception {
  7. /**
  8. * 自定义一个属性code
  9. */
  10. private int code;
  11. /**
  12. * 1.建议有一个无参的构造方法
  13. */
  14. public MyException() {
  15. super();
  16. }
  17. /**
  18. * 2.建议有一个只有一个message的构造方法
  19. * @param message
  20. */
  21. public MyException(String message) {
  22. super(message);
  23. }
  24. /**
  25. * 3.建议有一个可以接收Throwable类或自子类对象的构造方法
  26. * @param cause
  27. */
  28. public MyException(Throwable cause) {
  29. super(cause);
  30. }
  31. /**
  32. * 4.建议有一个可以接受自定义message和继承自Throwable类或其子类对象的参数的构造方法
  33. * @param message
  34. * @param cause
  35. */
  36. public MyException(String message, Throwable cause) {
  37. super(message, cause);
  38. }
  39. /**
  40. * 自定义一个构造函数
  41. * @param code
  42. * @param message
  43. */
  44. public MyException(int code, String message) {
  45. this(message);
  46. this.code = code;
  47. }
  48. /**
  49. * 获取异常码
  50. * @return
  51. */
  52. public int getCode() {
  53. return this.code;
  54. }
  55. }
  56. class ExceptionDemo {
  57. public int divide(int a, int b) throws MyException {
  58. if ( b == 0) {
  59. throw new MyException(100, "被除数不能为0");
  60. }
  61. return a / b;
  62. }
  63. }
  64. public class MyExceptionDemo {
  65. public static void main(String[] args) {
  66. ExceptionDemo demo = new ExceptionDemo();
  67. try {
  68. demo.divide(100, 0);
  69. } catch (MyException e) {
  70. System.out.println(e.getMessage() );
  71. e.printStackTrace();
  72. }
  73. System.out.println("demo结束");
  74. }
  75. }