1 try-catch 语句

基本与 C++ 中的一致。

  1. public static void main(String args[]) {
  2. try {
  3. BufferedReader in = new BufferedReader(System.in));
  4. System.out.print("Please input a number: ");
  5. String s = in.readLine();
  6. int n = Integer.parseInt(s);
  7. } catch (IOException ex) {
  8. ex.printStackTrace();
  9. } catch (NumberFormatException ex) {
  10. ex.printStackTrace();
  11. }
  12. }

运行时系统在调用栈中查找,从生成异常的方法开始进行回溯,直到找到 catch 语句的代码。

1.1 抛出异常

throw 异常对象;

1.2 捕获异常

  1. try {
  2. // ...
  3. } catch (异常类名 异常形参) { // 可选
  4. // ...
  5. } catch (异常类名 异常形参) {
  6. // ...
  7. } finally { // 可选
  8. }

1.3 异常的分类

  • Throwable
    • Error : JVM 错误
    • Exception : 异常

      一般所说的异常是指 Exception 及其子类

image.png

1.3.1 Exception 类

  • 构造方法
    • public Exception();
    • public Exception(String message);
    • Exception(String message, Throwable cause);
  • 方法
    • getMessage()
    • getCause()
    • printStackTrace()

1.3.2 多异常的处理

image.png

下面这个例子展示了 finally 的情况。

  1. public class TestTryFinally {
  2. static String output = "output ";
  3. public static void main(String args[]) {
  4. foo(1);
  5. System.out.println(output);
  6. }
  7. public static void foo(int i) {
  8. try {
  9. if (i == 1) {
  10. throw new Exception();
  11. }
  12. output += "1";
  13. } catch (Exception e) {
  14. output += "2";
  15. return;
  16. } finally {
  17. output += "3";
  18. }
  19. }
  20. }
  21. // 输出结果
  22. // output 23

1.3.3 受检的异常

image.png

  • RuntimeException 异常可以直接使用 if 语句处理。
  • main 函数也可以写 throws

下面是 throws 的例子:

  1. import java.io.*;
  2. public class TestTryThrowsToOther {
  3. public static void main(String args[]) {
  4. try {
  5. System.out.println("======Before======");
  6. readFile();
  7. System.out.println("======After=======");
  8. } catch (IOException e) {
  9. System.out.println(e);
  10. }
  11. }
  12. public static void readFile() throws IOException {
  13. FileInputStream in = new FileInputStream("test.txt");
  14. int b;
  15. b = in.read();
  16. while (b != -1) {
  17. System.out.print((char) b);
  18. b = in.read();
  19. }
  20. in.close();
  21. }
  22. }

1.4 try-with-resource

  1. try ( 类型 变量名 = new 类型 () ) {
  2. // ...
  3. }
  4. // 相当于自动添加了 finally { 变量.close(); }
  5. // 当然,变量必须是 Closable 的

2 自定义异常

image.png
重抛异常以及异常链接
image.png

下面是关于异常链接(多层异常)的例子:

  1. import java.io.*;
  2. public class hello {
  3. public static void main(String args[]) {
  4. try {
  5. BankATM.getBalanceInfo(12345L);
  6. } catch (Exception e) {
  7. System.out.println("something wrong: " + e);
  8. System.out.println("cause: " + e.getCause());
  9. }
  10. }
  11. }
  12. class DataHouse {
  13. public static void findData(long id) throws DataHouseException {
  14. if (id > 0 && id < 1000)
  15. System.out.println("id: " + id);
  16. else
  17. throw new DataHouseException("cannot find the id");
  18. }
  19. }
  20. class BankATM {
  21. public static void getBalanceInfo(long id) throws MyAppException {
  22. try {
  23. DataHouse.findData(id);
  24. } catch (DataHouseException e) {
  25. throw new MyAppException("invalid id", e);
  26. }
  27. }
  28. }
  29. class DataHouseException extends Exception {
  30. public DataHouseException(String message) {
  31. super(message);
  32. }
  33. }
  34. class MyAppException extends Exception {
  35. public MyAppException(String message) {
  36. super(message);
  37. }
  38. public MyAppException(String message, Exception cause) {
  39. super(message, cause);
  40. }
  41. }
  42. // 输出结果
  43. // something wrong: MyAppException: invalid id
  44. // cause: DataHouseException: cannot find the id