1. 引言
Stack Trace(调用栈)— 是在你的程序中发生错误(异常)之前被调用的方法列表。当程序发生异常时,Java 会自动把调用栈打印到屏幕。这就像“雪地上的脚印”:你能看到程序是沿着哪些步骤走到了错误。
类比:
想象你在迷宫里行走,突然撞上了一堵墙。Stack trace 就是一张地图,显示你在迷宫里走过哪些走廊,最终迷失方向。
Stack Trace 长什么样?
当程序出现错误时,Java 会打印类似如下的信息:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.divide(Main.java:10)
at Main.main(Main.java:5)
这里写了什么?
- Exception in thread "main" — 错误发生的线程(通常是 "main")。
- java.lang.ArithmeticException: / by zero — 异常类型及其消息。
- at Main.divide(Main.java:10) — 类 Main 中的 divide 方法,第 10 行。
- at Main.main(Main.java:5) — 类 Main 中的 main 方法,第 5 行。
每一行 at ... 都是调用栈中的一步。最上面一行是错误发生的位置。下面是调用该方法的方法,如此向下直到程序的起点。
2. 如何阅读 Stack Trace?
步骤 1:找到异常类型和消息
第一行总是包含错误类型及其描述:
java.lang.ArithmeticException: / by zero
这已经给出线索:错误与除以零有关。
步骤 2:查看第一条以 “at ...” 开头的行
这就是错误实际发生的位置:
at Main.divide(Main.java:10)
也就是说,错误发生在 Main 类的 divide 方法的第 10 行。
步骤 3:沿栈向上查看
下一行显示是谁调用了这个方法:
at Main.main(Main.java:5)
也就是说,main 方法调用了 divide,错误被“向上抛出”。行号为 5。
步骤 4:优先寻找你自己的类
在很长的调用栈中经常会有系统方法(例如来自包 java.util、java.io)。
你的类通常离列表开头更近。 查看类名和文件名——找出属于你的!
3. 示例:解析一个真实的 Stack Trace
代码:
public class Main
{
public static void main(String[] args)
{
int result = divide(10, 0);
System.out.println("结果: " + result);
}
public static int divide(int a, int b)
{
return a / b;
}
}
错误:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.divide(Main.java:8)
at Main.main(Main.java:3)
解析:
- 错误:除以零(ArithmeticException)。
- 发生在 divide 方法的第 8 行。
- 由 main 方法第 3 行调用触发。
怎么办?
打开文件 Main.java,定位到第 8 行——可以看到除以零。修复它即可!
4. 包含多个方法的 Stack Trace
代码:
public class Main
{
public static void main(String[] args)
{
process();
}
public static void process()
{
calculate();
}
public static void calculate()
{
int[] arr = {1, 2, 3};
System.out.println(arr[10]); // 错误!
}
}
错误:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 3
at Main.calculate(Main.java:11)
at Main.process(Main.java:7)
at Main.main(Main.java:3)
解析:
- 错误:数组越界(ArrayIndexOutOfBoundsException)。
- 发生在 calculate(第 11 行)。
- 由 process 调用(第 7 行)。
- 由 main 调用(第 3 行)。
结论:
Stack trace 展示了程序到达错误位置的完整路径。
5. 使用 Stack Trace 时的常见错误
错误 1:忽略 Stack Trace。
新手常常只看“红色报错”,而不阅读调用栈。别这样!Stack trace 是指引你定位缺陷的位置的线索。
错误 2:把“错误类型那一行”和“发生位置那一行”混为一谈。
重要:第一行是错误类型;发生位置在第一条 at ... 行。
错误 3:到系统类里找错误。
如果你看到类似 at java.base/java.util.Scanner.nextInt(Scanner.java:123) 这样的行,不要急着去翻 Java 源码。请看是谁在你的代码里调用了这个方法。
错误 4:没有利用行号。
行号是你最好的朋友。打开文件,找到对应的行——错误就在那里。
错误 5:没理解 Stack Trace 是一条“路径”。
Stack trace 展示程序是如何走到错误的。有时问题不在最顶端那一行,而在你调用该方法的方式上。
GO TO FULL VERSION