当捕获到异常的时候, 往往需要进行一定的处理。比较简单且直接的一种处理方式就是打印出异常的栈轨迹, 也就是英文里的Stack Trace。
提起栈轨迹这件事, 很可能有很多人跟我的情况是一样的, 第一个出现的念头就是()这个方法的存在。事实上, 不单单只有这一个方法存在, 此外还有一些别的一些内容事项同样也是跟栈轨迹有着关联的。
1、()
必须要先把这个事儿弄清楚才对, 这个方法压根儿就不是从哪个类里面蹦出来的。类本身干的事儿除了定义那么几个构造器之外, 剩下的所有方法全都是从它那个父类上面继承得来。至于那些跟异常挂钩在一起的方法呢, 则全都是从.类那里头顺带继承过来的。<>()正是这其中一个。
采用这个方法的话, 就会把对象的栈轨迹信息打印到标准错误输出流上面, 具体输出的样子大概会呈现出下面的这种样式:
java.lang.
这个方法是在Java语言的源代码第9行这个位置发生的。
at .(.java:6)
at .main(.java:3)
输出的第一行是使用当前方法所得到的结果, 而从第二行开始的后续内容, 则是此前利用该方法所存储下来的数据。关于这个方法的更多信息, 我们将在后面的章节里进行讲解。
接下来我们来看这样具体的一个实例情况。
class {
void f() {
抛出异常, 内容为存在问题。
void g() {
f();
主程序的入口处是void类型, 并且在这个主函数的括号里包含了参数部分。
try {
g();
}catch( e) {
e.();
这个示例所产生的最终呈现结果为以下这般。
java.lang.: 出问题啦!
at .f(.java:3)
在点g这个方法里面, 也就是java第六行的位置。
at .main(.java:10)
在这个例子里面, 方法f()会抛出异常, 然后方法g()去调用那个方法f(), 接着在main方法里面去捕获这个异常, 还把栈轨迹信息打印了出来。因此, 输出的内容按照先后顺序, 依次展示了从f到g再到main的这个过程。
2、()方法
这个方法提供了对()方法所打印信息的编程访问。它会返回一个栈轨迹元素的数组。以上面的输出为例。输出的第2-4行每一行的内容对应一个栈轨迹元素。将这些栈轨迹元素保存在一个数组中。每个元素对应栈的一个栈帧。数组的第一个元素保存的是栈顶元素。也就是上面的f。最后一个元素保存的栈底元素。
这是一个例子, 在这个例子中, 会使用括号来访问这些存储在轨迹栈里面面的元素, 然后把这些内容给打印出来展示给大家看:
class {
void f() {
抛出异常, 内容为存在问题。
void g() {
f();
主程序的入口处是void类型, 并且在这个主函数的括号里包含了参数部分。
try {
g();
}catch( e) {
e.();
(点)出(句号), 然后输入连在一起的横杠组成的长条。
for( elem : e.()) {
这个动作会作用于特定的元素。
这样的输出和()的输出基本上是一样的,具体如下:
java.lang.: 出问题啦!
at .f(.java:3)
在点g这个方法里面, 也就是java第六行的位置。
at .main(.java:10)
.f(.java:3)
.g(.java:6)
.main(.java:10)