Java 例外


例外是一个事件,当发生例外时,程序中断正常的执行顺序。


例外分为三种:

  • checked例外,可预料和恢复的例外。checked例外包含除RuntimeException类、Error类及它们的子类外的其它Exception类。
  • 运行时(runtime)例外,不可预料和恢复的例外,发生运行时例外表示程序存在bug。运行时例外包含RuntimeException类及其子类。例如NullPointerException当对象值为null,调用对象的方法时抛出,程序在调用对象方法前,检查对象是否为null。
  • error,不可预料和恢复的例外,程序没能力处理这类例外。error包含Error类及其子类。例如:OutOfMemoryError会在内存用完后抛出,程序会退出。

运行时例外和error合称为unchecked例外。

例外处理

例外处理有两种写法:

  • 使用try、catch、finally的写法。catch块只是在捕获到例外时才会执行。finally块中一般用来释放资源,一定会执行。
  • 使用try-with-resources写法。不需要写finally块,只需要资源实现了AutoCloseable接口。不论程序是否抛出例外,资源会自动释放。写法简洁,建议使用该种写法。

下面是try、catch、finally写法的例子:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TryCatch {
    public static void main(String[] args) {
        BufferedReader in = null;
        try {
      in = new BufferedReader(new FileReader("not_exist_file"));
      String str;

      while ((str = in.readLine()) != null) {
          System.out.println(str);
      }
    } catch (IOException e) {
      e.printStackTrace(System.out);
            // error: java.io.FileNotFoundException: not_exist_file
    } finally {
            System.out.println("release resource.");    // release resource.
        if (in != null) {
          try {
              in.close();
          } catch (Exception e) {
          }
        }
    }
    }
}


下面是try-with-resources写法的例子:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TryResource {
public static void main(String[] args) {
    try (BufferedReader in = new BufferedReader(new FileReader("not_exist_file"))) {
        String str;

        while ((str = in.readLine()) != null) {
            System.out.println(str);
        }
    } catch (IOException e) {
        e.printStackTrace(System.out);
        // java.io.FileNotFoundException: not_exist_file (No such file or directory)
    }
    }
}

Checked例外

必须在方法的定义上抛出Checked例外。

下面是Checked例外的例子:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Checked {
    public static void main(String[] args) {
        try {
            new Checked().printFile();
        } catch (IOException e) {
            e.printStackTrace(System.out);
            // java.io.FileNotFoundException: not_exist_file (No such file or directory)
        }
    }

    public void printFile() throws IOException {
        BufferedReader in = null;

        try {
            in = new BufferedReader(new FileReader("not_exist_file"));
            String str;

            while ((str = in.readLine()) != null) {
            System.out.println(str);
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                }
            }
        }
    }
}

Runtime例外

不需要在方法的定义上抛出Runtime例外。

下面是Runtime例外的例子:

public class RuntimeEx {
    public static void main(String[] args) {
        try {
            String name = new RuntimeEx().getFileName(null);
            System.out.println("file name : " + name);
        } catch (NullPointerException e) {
            e.printStackTrace(System.out); // error: java.lang.NullPointerException
        }
    }

    public String getFileName(String path) {
        return path.substring(path.lastIndexOf('/'));
    }
}