Java抛出异常时栈追踪行号对应e.getMessage()而非throw语句是否正常?
结论
这是符合Java规范的正常行为,不需要担心代码或者运行环境出问题。
原因解释
- 异常的栈追踪快照是在
Throwable类的构造函数执行时生成的,本质记录的是异常对象被实例化的代码位置,而非throw关键字所在的代码位置。 - 你示例中的
throw new RuntimeException(...)语句被拆成了多行书写,e.getMessage()作为构造参数的一部分单独写在第49行。Java代码在编译时,会为每一段字节码指令关联对应的源代码行号(行号表),构造RuntimeException对象前需要先完成所有参数的求值运算,此处参数中的字符串拼接操作、e.getMessage()调用的字节码被编译器关联到了第49行,最终异常构造的指令也被映射到了这一行,所以栈追踪显示的行号就是第49行。
验证方式
你可以通过两种修改方式验证逻辑:
- 将
throw new RuntimeException("Run time error " + e.getMessage(), e);整行写在同一行,栈追踪的行号会自动变为throw语句所在的行。 - 提前把异常信息赋值给单独变量,再传入构造函数:
catch (Exception e) { String msg = "Run time error " + e.getMessage(); throw new RuntimeException(msg, e); }
此时栈追踪显示的行号会是throw new RuntimeException(msg, e);所在的行。
内容的提问来源于stack exchange,提问作者Mohammad Karmi
相关产品推荐
相关产品推荐

