笔友城堡 - 可定义的个人主页

前言

简单记录一下Java面试中常被问的异常相关知识点,简单记录于此,方便自己查阅和学习。

主要涉及ThrowableErrorExceptionRuntimeException等相关内容。

正文

异常体系结构

Throwable
 ├── Error(错误)
 │    ├── OutOfMemoryError
 │    ├── StackOverflowError
 │    └── NoClassDefFoundError
 └── Exception(异常)
      ├── RuntimeException(运行时异常)
      │    ├── NullPointerException
      │    ├── ArrayIndexOutOfBoundsException
      │    ├── ClassCastException
      │    └── ArithmeticException
      └── 非RuntimeException(受检异常)
           ├── IOException
           ├── SQLException
           └── InterruptedException
  1. Error表示严重系统错误,程序无法恢复

  2. Exception表示程序可处理的异常情况

Error和Exception的区别

对比点ErrorException
是否程序可控❌ 不可控✅ 可控
是否建议捕获❌ 不建议✅ 建议
典型场景JVM 崩溃、系统级问题业务逻辑异常
例子OOM、StackOverflowIOException

受检异常和非受检异常

受检异常

编译期检查,必须catch或throws,且继承自Exception,但不是RuntimeException

常见:

  • IOException
  • SQLException
  • FileNotFoundException
public void read() throws IOException {
    ...
}
非受检异常

编译期不检查,可处理也可不处理,继承自RuntimeException

常见:

  • NullPointerException

  • ArrayIndexOutOfBoundsException

  • IllegalArgumentException

对比表
对比点受检异常非受检异常
编译期检查
是否强制处理
继承关系Exception(但不是RuntimeException)RuntimeException
使用场景可预知、可恢复程序错误

throw和throws区别

对比点throwthrows
位置方法体内方法签名
作用抛出异常对象声明可能抛出的异常
数量一次一个可多个
throw

用于方法内,代码中可能存在的异常,抛出异常

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    throw new RuntimeException(e);
}

或者

public static int getInt(@NonNull String status_uri, @NonNull ContentResolver cr, String name) throws StatusNotFoundException {
    Uri uri = Uri.parse(status_uri + "/" + name);
    Cursor cursor = cr.query(uri, null, null, null, null);
    if (cursor != null) {
        cursor.moveToNext();
        try {
            return cursor.getInt(VAL_COLUMN_ID);//VAL_COLUMN_ID=1
        } catch (Exception e) {
            throw new StatusNotFoundException(name);
        } finally {
            cursor.close();
        }
    } else {
        throw new StatusNotFoundException(name);
    }
}
throws

方法名后,给方法修饰的,可以存在多个异常。

public void reboot() throws android.os.RemoteException{
    //略
}

或者

public void saveDatabase() throws IOException, SQLException{
    //略
}

自定义异常

public class BusinessException extends RuntimeException {
    private String code;
    public BusinessException(String message, String code) {
        super(message);
        this.code = code;
    }
}

业务中推荐继承RuntimeException

问答

1. finally 一定会执行吗?
  1. 大多数情况会执行

  2. 以下情况不会:

    1. System.exit(0)
    2. JVM崩溃
    3. 守护线程被强制结束
2. finally和return的执行顺序
public int test() {
    try {
        Log.d(TAG, "test 1: ");
        return 1;
    } finally {
        Log.d(TAG, "test 2 : ");
        return 2;
    }
}

返回结果:2

3. finally 的return 会覆盖 try 的 return

会覆盖,

所以不要在finally写return。

4. OOM 属于 Error 还是 Exception?

Error

Error表示JVM无法恢复的严重错误

5. RuntimeException 可以不处理吗?

可以,但不代表不应该处理

6. try-with-resources 了解吗?

Java 7+新增的,自动关闭资源(实现 AutoCloseable)

try (BufferedReader br = new BufferedReader(new FileReader("a.txt"))) {
    ...
}

小结

  1. Java中所有异常都继承自Throwable,分为Error和Exception

  2. Error表示JVM无法恢复的严重错误,如 OOM

  3. Exception 表示程序可处理的异常

  4. Exception 又分为受检异常和非受检异常:

    1. 受检异常编译期必须处理,如 IOException;

    1. 非受检异常继承自RuntimeException,编译期不强制处理

  5. try-catch-finally 用于异常处理,finally 一般用于资源释放,不建议在 finally 中使用 return

参考文章

AI

相关网址

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...