异常是一种特殊的类,在创建异常时会保存创建时的方法调用堆栈镜像。即,为了保留异常出现时的实时堆栈信息,不应复用异常,每个异常均需单独new方式生成。
下面演示一段有问题的代码并进行分析
1.问题代码
a)自定义异常定义
package demo.bce;
public class MyException extends RuntimeException {
private static final long serialVersionUID = -3802919537257556719L;
private String id;
public MyException(String id) {
super();
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@SuppressWarnings("unused")
private MyException() {
}
}
b)自定义异常常量
package demo.bce;
public final class MyExceptionContext {
// x1,x2,y1,y2的Throw相关堆栈信息在创建时一次性生成(不再变化)
// 即使用此异常会得到错误的堆栈描述信息
public static final MyException x1 = new MyException("X1");
public static final MyException x2 = new MyException("X2");
}
c)测试代码
package demo.bce;
public class MyMain {
public static void main(String[] args) {
testx();
}
// ///
private static void testx() {
try {
x11();
} catch (Exception e) {
e.printStackTrace();
}
try {
x12();
} catch (Exception e) {
e.printStackTrace();
}
try {
x21();
} catch (Exception e) {
e.printStackTrace();
}
try {
x22();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void x11() {
throw MyExceptionContext.x1;
}
private static void x12() {
throw MyExceptionContext.x2;
}
private static void x21() {
throw MyExceptionContext.x1;
}
private static void x22() {
throw MyExceptionContext.x2;
}
}
d)测试结果
demo.bce.MyException
at
demo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:7)
at demo.bce.MyMain.x11(MyMain.java:36)
at demo.bce.MyMain.testx(MyMain.java:14)
at demo.bce.MyMain.main(MyMain.java:7)
demo.bce.MyException
at
demo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:8)
at demo.bce.MyMain.x11(MyMain.java:36)
at demo.bce.MyMain.testx(MyMain.java:14)
at demo.bce.MyMain.main(MyMain.java:7)
demo.bce.MyException
at
demo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:7)
at demo.bce.MyMain.x11(MyMain.java:36)
at demo.bce.MyMain.testx(MyMain.java:14)
at demo.bce.MyMain.main(MyMain.java:7)
demo.bce.MyException
at
demo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:8)
at demo.bce.MyMain.x11(MyMain.java:36)
at demo.bce.MyMain.testx(MyMain.java:14)
at demo.bce.MyMain.main(MyMain.java:7)
代码实际上在四个不同的方法中抛出了两个不同的异常,但抛到四个异常的堆栈信息居然完全一致。
另外,x11和x21虽然抛同一个异常,但x11的异常无stackTrace,x21的异常有stackTrace信息。
2.代码分析和猜想
在MyExceptionContext首次被调用时才生成常量异常x1和x2。注意x1和x2是同时生成的,且基本上处于相同的方法调用环境。故x1和x2的方法调用堆栈信息基本一致,进而在实际使用时严重误导异常的抛出分析。
另外,通常情况下,异常是需要设置cause的。因此,也不应该尝试常量异常(cause每次可能不一样)。
3.简单总结
使用异常时实时new一个出来返回以获取正确方法调用堆栈信息。
分享到:
相关推荐
复制代码 代码如下: /** * 获取变量名 * * @param $string * @... //在函数中不要直拉遍历$GLOBALS,会出现堆栈问题 foreach($allvar as $k=>$v){ //变量值相同,可能不是相同变量,因多个变量的值可能相同 if ($src
摘要:Delphi源码,系统相关,动态数组,静态数组 示Delphi例用于演示栈分配中一... 静态数组的局部变量总会在栈上分配,因此如果堆栈大小不够,将会导致异常。 本例中调用StackOver()总会发生异常:Stack overflow。
使用MERN堆栈构建的Bug跟踪器Web应用程序,并使用JWT添加了身份验证 开始吧 首先,在/ api下使用变量SECRET_KEY和URI创建一个.env文件: SECRET_KEY:用于JWT签名的密钥 URI:Mongo数据库的URI 端口:API端口 接...
异常信息应该包括两类信息:案发现场信息和异常堆栈信息。 B .日志文件推荐至少保存15天,因为有些异常具备以“周”为频次发生的特点。 C .避免重复打印日志,浪费磁盘空间,务必在log4j.xml中设置additivity=...
本程序基于东灿的异常调试模块5.2部分版权信息如下: 1. 该模块功能是补足易错误管理器无法捕捉的异常。 2. 本模块可以截获许多异常,比如内存读写错误,非法汇编指令,算术异常,其他异常等等。 3. 本模块拥有try/...
我的演示代码,建议您在尝试该代码时阅读。
错误跟踪器| PERN-TypeScript 使用PERN + TS制作的错误跟踪应用 ...Dotenv-从.env文件加载环境变量 特征 身份验证(使用用户名和密码登录/注册) CRUD项目,可以添加成员以进行小组工作 具有标题,描述和优先
这些信息包括临时变量的值、内存信息、调用堆栈、汇编信息、寄存器信息等。 七、多多动手,尝试调试 调试需要大量的实践和经验。初学者可能需要花费80%的时间在写代码,20%的时间在调试。但是一个程序员可能需要...
NovalIDE 1.1.7 隆重发布,新版本添加了以下重磅功能!...可查看调式堆栈信息 允许调式添加断点和监视变量 支持了一些文本格式化操作 修复了已知的一些BUG 软件官方网址:http://www.novalide.com
更正for keil c51 移植的堆栈在某种情况下初始值错误。 0.51版 2002年3月10日 修改函数OSWait使其占用资源更少,兼容性更好。 更正for keil c51 移植的C_OSCtxSw函数的错误。 0.50版 2002年2月22日
* 最下面的一些提示栏还是很有帮助的,比如调用堆栈,局部变量,监视等。 四、调试工具栏 调试工具栏中有很多按钮,下面是常用的几个: * 点击绿色三角则让程序继续执行,如果后面有断点或者stop则又会中断,否则...
本教程共分为5个部分,第一部分是C语言...11_异常类型_异常变量的生命周期下_传智扫地僧 12_中午知识点梳理 13_异常的层次结构_传智扫地僧 14_标准异常库 15_流类库结构 16_标准IO_输入api_上 17_标准IO_输入api_下 ...
变量生命周期的混乱往往会导致大量的程序Bug,接下来将介绍java是怎样替我们完成所有的清理工作,从而大大地简化这个问题的。 作用域 大多数过程型语言都有作用域(Scope)的概念。作用域决定了在其内定义的变量...
可能我们看到最多的就是catch中的e参数,里面会有一个StackTrace,然后不可否认的这玩意太有用了,它会把调用堆栈中的信息输出出来,有了它,我们就可以快速的知道运行代码的执行流并且快速的定位到问题。...
文件信息:对包含在变量中的文件列表进行操作 10-4. 在for循环中操作文件 10-5. 在for循环中省略[list] 10-6. 使用命令替换来产生for循环的[list] 10-7. 对于二进制文件的一个grep替换 10-8. 列出系统上的所有用户 ...
文件信息:对包含在变量中的文件列表进行操作 10-4. 在for 循环中操作文件 10-5. 在for 循环中省略[list] 10-6. 使用命令替换来产生for 循环的[list] 10-7. 对于二进制文件的一个grep 替换 10-8. 列出系统上的所有...
3、修正“类_环境存取->读环境变量”不能读取当前进程环境变量的BUG,感谢易友【@詠不言敗】反馈。 4、修正“文本_逐字分割”返回数组不清除会保留上次内容的问题,感谢易友【@JadeジYu】反馈。 5、新增“文本_是否...
在系统开发过程中出现的bug相对而言是比较好解决的,花费在这个上面的调试代价不是很大,但是在系统集成后的bug往往是难以定位的bug(最好方式是打桩,通过打桩可以初步锁定出错的位置,如:进入函数前打印日志,...
解决方法:将该工程的主要的 main.c 文件,lcd.c 文件,lcd.h 头文件等,复制到另一个正常运行的标准库工程里面,修改 bug 后,运行,好了。 问题 10:某教程的 stm32F1 的串口配置文件结构比较好,但确少:NVIC_...
本文主要讲解Android虚拟机动态调试背后涉及到的技术原理,除了JDWP协议细节,还包括任意位置断点、堆栈输出、变量值获取等基础调试功能的具体实现。另外本文提供了一款新的android动态调试工具——AVMDBG,提供调试...