目录

[Java核心技术] Java异常和异常处理

Java 核心技术读书笔记——Java异常和异常处理

1 Java异常分类

异常:程序不正常的行为或者状态

Throwable

所有错误的祖先

Error

系统内部错误或者资源耗尽,可以不用处理。

Exception

程序有关异常,重点关注

  • RuntimeException:程序自身的错误
    • 5/0,空指针,数组越界…
  • 非RuntimeException:外界相关的错误
    • 打开一个不存在文件
    • 加载一个不存在的类
  • Unchecked Exception:(编译器不会辅助检查的,需要程序员自己管的)异常,包括Error子类和RuntimeException子类。
  • RuntimeExceptionException的子类:(编译器会辅助检查的)异常,checked exception
  • 注意:编译器会检查程序是否为checked exception配置了处理。如果没有处理,会报错。

2 Java异常处理

  • 允许用户及时保存结果
  • 抓住异常,分析异常内容
  • 控制程序返回到安全状态

try-catch-finally

  • 一种保护代码正常运行的机制
    • try:正常业务逻辑代码。
    • catch:当try发生异常,将执行catch代码。若无异常,则绕之。
    • finally:当try或catch执行结束后,必须要执行finally。
  • 异常结构
    • try...catch(catch可以有多个,下同)
    • try...catch...finally
    • try...finally
  • try必须有,catchfinally至少要有一个
  • catch块可以有多个,每个有不同的入口形参。当已发生的异常和某一个catch块中的形参类型一致,那么将执行该catch块中的代码。如果没有一个匹配,catch也不会被触发。最后都进入finally块。
  • 进入catch块后,并不会返回到try发生异常的位置,也不会执行后续的catch块,一个异常只能进入一个catch块。
  • catch块的异常匹配是从上而下进行匹配,所以一般是将小的异常写在前面,而一些大(宽泛)的异常则写在末尾。
  • try-catch-finally每个模块里面也会发生异常,所以也可以在内部继续写一个完整的try结构。

throws

  • 方法存在可能异常的语句,但不处理,那么可以使用throws来声明异常。
  • 调用带有throws异常(checked exception)的方法,要么处理这些异常,或者再次向外throws,直到main函数为止。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class ThrowsDemo
{
  public static void main(String [] args)
  {
    try
    {
      int result = new Test().divide( 3, 1 );
      System.out.println("the 1st result is" + result );
    }
    catch(ArithmeticException ex)
    {
      ex.printStackTrace();
    }
    int result = new Test().divide( 3, 0 );
    System.out.println("the 2nd result is" + result );
  }
}
class Test
{
  //ArithmeticException is a RuntimeException, not checked exception
  public int divide(int x, int y) throws ArithmeticException
  {
    int result = x/y;
    return x/y;
  }
}

覆盖/继承

  • 一个方法被覆盖,覆盖它的所有方法必须抛出相同的异常,或者异常的子类。
  • 如果父类的方法抛出多个异常,那么重写的子类方法必须抛出那些异常的子集,也就是不能抛出新的异常。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    // Father.java
    public class Father {
      public void f1() throws ArithmeticException
      {
    
      }
    }
    
    // Son.java
    public class Son extends Father {
      public void f1() throws IOException // error
      {
        //子类重写方法,
        //所抛出的异常不能超出父类规定的范围
      }
    }
    

3 自定义异常

  • 自定义异常,需要继承Exception类或者子类
    • 继承自Exception,就变成Checked Exception
    • 继承自RuntimeException,就变成UncheckedException
  • 自定义重点在构造函数
    • 调用父类Exceptionmessage构造函数
    • 可以自定义自己的成员变量
  • 在程序中采用throw主动抛出异常
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// MyException.java
public class MyException extends Exception {

  private String returnCode ;  //异常对应的返回码
  private String returnMsg;  //异常对应的描述信息
  
  public MyException() {
    super();
  }

  public MyException(String returnMsg) {
    super(returnMsg);
    this.returnMsg = returnMsg;
  }

  public MyException(String returnCode, String returnMsg) {
    super();
    this.returnCode = returnCode;
    this.returnMsg = returnMsg;
  }

  public String getReturnCode() {
    return returnCode;
  }

  public String getreturnMsg() {
    return returnMsg;
  }
}

//MyExceptionTest.java
public class MyExceptionTest {
  public static void testException() throws MyException {  
       throw new MyException("10001", "The reason of myException");  
         
    }  
  
  public static void main(String[] args)  {

    MyExceptionTest.testException(); //error 需要使用try-catch-finally
    
//    try {
//      MyExceptionTest.testException();
//    } catch (MyException e) {
//      e.printStackTrace();
//      System.out.println("returnCode:"+e.getReturnCode());
//      System.out.println("returnMsg:"+e.getreturnMsg());
//    }
  }
}