简单记录一下Java面试中常被问的异常相关知识点,简单记录于此,方便自己查阅和学习。
主要涉及Throwable、Error、Exception、RuntimeException等相关内容。
正文
异常体系结构
Throwable ├── Error(错误) │ ├── OutOfMemoryError │ ├── StackOverflowError │ └── NoClassDefFoundError └── Exception(异常) ├── RuntimeException(运行时异常) │ ├── NullPointerException │ ├── ArrayIndexOutOfBoundsException │ ├── ClassCastException │ └── ArithmeticException └── 非RuntimeException(受检异常) ├── IOException ├── SQLException └── InterruptedException
Error表示严重系统错误,程序无法恢复
Exception表示程序可处理的异常情况
Error和Exception的区别
| 对比点 | Error | Exception |
|---|---|---|
| 是否程序可控 | ❌ 不可控 | ✅ 可控 |
| 是否建议捕获 | ❌ 不建议 | ✅ 建议 |
| 典型场景 | JVM 崩溃、系统级问题 | 业务逻辑异常 |
| 例子 | OOM、StackOverflow | IOException |
受检异常和非受检异常
编译期检查,必须catch或throws,且继承自Exception,但不是RuntimeException
常见:
- IOException
- SQLException
- FileNotFoundException
public void read() throws IOException { ... }
非受检异常
编译期不检查,可处理也可不处理,继承自RuntimeException
常见:
NullPointerException
ArrayIndexOutOfBoundsException
IllegalArgumentException
对比表
| 对比点 | 受检异常 | 非受检异常 |
|---|---|---|
| 编译期检查 | ✅ | ❌ |
| 是否强制处理 | ✅ | ❌ |
| 继承关系 | Exception(但不是RuntimeException) | RuntimeException |
| 使用场景 | 可预知、可恢复 | 程序错误 |
throw和throws区别
| 对比点 | throw | throws |
|---|---|---|
| 位置 | 方法体内 | 方法签名 |
| 作用 | 抛出异常对象 | 声明可能抛出的异常 |
| 数量 | 一次一个 | 可多个 |
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. 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"))) { ... }
小结
Java中所有异常都继承自Throwable,分为Error和Exception
Error表示JVM无法恢复的严重错误,如 OOM
Exception 表示程序可处理的异常
Exception 又分为受检异常和非受检异常:
受检异常编译期必须处理,如 IOException;
非受检异常继承自RuntimeException,编译期不强制处理
try-catch-finally 用于异常处理,finally 一般用于资源释放,不建议在 finally 中使用 return
参考文章
相关网址
暂无评论...
