Java学习笔记(五)
Java核心技术卷一基础知识第10版
#异常、断言和日志
#异常
- 在 Java 程序设计语言中,异常对象都是派生于
Throwable
类的一个实例。 Error
类层次结构描述了 Java 运行时系统的内部错误和资源耗尽错误。除了通告给用户,并尽力使程序安全地终止之外,再无能为力。- 在设计 Java 程序时, 需要关注
Exception
层次结构:- RuntimeException:由程序错误导致的异常。
- 其它异常:程序本身没有问题,但由于像
I/O错误
这类问题导致的异常。
- 如果出现
RuntimeException
异常,那么就一定是你的问题。 - 派生于 Error 类或 RuntimeException 类的所有异常称为
非受查(unchecked)异常
,所有其他的异常称为受查(checked)异常
。 - 一个方法必须声明所有可能抛出的受查异常,而非受查异常要么不可控制(Error),要么就应该避免发生(RuntimeException)。
- 抛出异常:
- 找到一个合适的异常类。
- 创建这个类的一个对象。
- 将对象抛出。
- 如果调用了一个抛出受查异常的方法,就必须对它进行处理,或者继续传递。
- 应该捕获那些
知道如何处理的异常
,而将那些不知道怎样处理的异常
继续进行传递。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
30public void read(String filename)
{
try
{
InputStream in = new FileInputStream(filename);
int b;
while ((b = in.read()) != -1)
{
// process input
...
}
}
catch (IOException exception)
{
exception.printStackTrace();
}
}
// 更好的选择👇
public void read(String filename) throws IOException
{
InputStream in = new FileInputStream(filename);
int b;
while ((b = in.read()) != -1)
{
// process input
...
}
} - 如果编写一个覆盖超类的方法,而这个方法又没有抛出异常,那么这个方法就必须捕获方法代码中出现的每一个受查异常。
- 不允许在子类的 throws 说明符中出现超过超类方法所列出的异常类范围。
- 强烈建议使用这种包装技术,这样可以让用户抛出子系统中的高级异常,而不会丢失原始异常的细节。
1
2
3
4
5
6
7
8
9
10
11
12
13
14try
{
// access the database
...
}
catch (SQLException e)
{
Throwable se = new ServletException("database error");
se.initCause(e);
throw se;
}
// 获得原始异常
Throwable e = se.getCause(); - 不管是否有异常被捕获,
finally
子句中的代码都被执行。 带资源的 try 语句
可以很好地处理“如果 try 块抛出一个异常,而且 close 方法也抛出一个异常”的问题。- 异常处理不能代替简单的测试。因为异常捕获的耗时较长。
- 不要过分地细化异常。
- 不要压制异常。[1]
- 在检测错误时,“苛刻”要比“放任”更好。尽早抛出异常可以让使用者更方便的处理,而未知的异常才是最难检查的。
- 不要羞于传递异常。
#断言
1 | assert 条件; |
- 断言失败是致命的、不可恢复的错误。
- 断言检查只用于开发和测阶段。
- 7个日志记录器级别:
- SEVERE
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINEST
没太看懂 ↩︎