Bug分析之异常变量堆栈信息

  异常是一种特殊的类,在创建异常时会保存创建时的方法调用堆栈镜像。即,为了保留异常出现时的实时堆栈信息,不应复用异常,每个异常均需单独new方式生成。

  下面演示一段有问题的代码并进行分析

  1、问题代码

  a)自定义异常定义

  

    packagedemo.bce; publicclassMyExceptionextendsRuntimeException{ privatestaticfinallongserialVersionUID=-3802919537257556719L; privateStringid; publicMyException(Stringid){ super(); this.id=id; } publicStringgetId(){ returnid; } publicvoidsetId(Stringid){ this.id=id; } @SuppressWarnings(“unused”) privateMyException(){ } }

  b)自定义异常常量

  

    packagedemo.bce; publicfinalclassMyExceptionContext{ //x1,x2,y1,y2的Throw相关堆栈信息在创建时一次性生成(不再变化)//即使用此异常会得到错误的堆栈描述信息publicstaticfinalMyExceptionx1=newMyException(“X1”); publicstaticfinalMyExceptionx2=newMyException(“X2”); }

  c)测试代码

  package demo.bce;

  

    publicclassMyMain{ publicstaticvoidmain(String[]args){ testx(); } /////privatestaticvoidtestx(){ try{ x11(); }catch(Exceptione){ e.printStackTrace(); } try{ x12(); }catch(Exceptione){ e.printStackTrace(); } try{ x21(); }catch(Exceptione){ e.printStackTrace(); } try{ x22(); }catch(Exceptione){ e.printStackTrace(); } } privatestaticvoidx11(){ throwMyExceptionContext.x1; } privatestaticvoidx12(){ throwMyExceptionContext.x2; } privatestaticvoidx21(){ throwMyExceptionContext.x1; } privatestaticvoidx22(){ throwMyExceptionContext.x2; } }

  d)测试结果

  

    demo.bce.MyException atdemo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:7) atdemo.bce.MyMain.x11(MyMain.java:36) atdemo.bce.MyMain.testx(MyMain.java:14) atdemo.bce.MyMain.main(MyMain.java:7) demo.bce.MyException atdemo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:8) atdemo.bce.MyMain.x11(MyMain.java:36) atdemo.bce.MyMain.testx(MyMain.java:14) atdemo.bce.MyMain.main(MyMain.java:7) demo.bce.MyException atdemo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:7) atdemo.bce.MyMain.x11(MyMain.java:36) atdemo.bce.MyMain.testx(MyMain.java:14) atdemo.bce.MyMain.main(MyMain.java:7) demo.bce.MyException atdemo.bce.MyExceptionContext.<clinit>(MyExceptionContext.java:8) atdemo.bce.MyMain.x11(MyMain.java:36) atdemo.bce.MyMain.testx(MyMain.java:14) atdemo.bce.MyMain.main(MyMain.java:7)

  代码实际上在四个不同的方法中抛出了两个不同的异常,但抛到四个异常的堆栈信息居然完全一致。

  另外,x11和x21虽然抛同一个异常,但x11的异常无stackTrace,x21的异常有stackTrace信息。

  2、代码分析和猜想

  在MyExceptionContext首次被调用时才生成常量异常x1和x2。注意x1和x2是同时生成的,且基本上处于相同的方法调用环境。故x1和x2的方法调用堆栈信息基本一致,进而在实际使用时严重误导异常的抛出分析。

  另外,通常情况下,异常是需要设置cause的。因此,也不应该尝试常量异常(cause每次可能不一样)。

  3、简单总结

  使用异常时实时new一个出来返回以获取正确方法调用堆栈信息。

父母养我不容易,我在学校争口气。

Bug分析之异常变量堆栈信息

相关文章:

你感兴趣的文章:

标签云: