网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  重新“掷”出违例     
  文章作者:未知  文章来源:水木森林  
  查看:75次  录入:管理员--2007-11-17  
 
  在某些情况下,我们想重新掷出刚才产生过的违例,特别是在用exception捕获所有可能的违例时。由于我们已拥有当前违例的句柄,所以只需简单地重新掷出那个句柄即可。下面是一个例子:
  catch(exception e) {
  system.out.println("一个违例已经产生");
  throw e;
  }
  重新“掷”出一个违例导致违例进入更高一级环境的违例控制器中。用于同一个try块的任何更进一步的catch从句仍然会被忽略。此外,与违例对象有关的所有东西都会得到保留,所以用于捕获特定违例类型的更高一级的控制器可以从那个对象里提取出所有信息。
  若只是简单地重新掷出当前违例,我们打印出来的、与printstacktrace()内的那个违例有关的信息会与违例的起源地对应,而不是与重新掷出它的地点对应。若想安装新的堆栈跟踪信息,可调用fillinstacktrace(),它会返回一个特殊的违例对象。这个违例的创建过程如下:将当前堆栈的信息填充到原来的违例对象里。下面列出它的形式:
  
  //: rethrowing.java
  // demonstrating fillinstacktrace()
  
  public class rethrowing {
   public static void f() throws exception {
    system.out.println(
     "originating the exception in f()");
    throw new exception("thrown from f()");
   }
   public static void g() throws throwable {
    try {
     f();
    } catch(exception e) {
     system.out.println(
      "inside g(), e.printstacktrace()");
     e.printstacktrace();
     throw e; // 17
     // throw e.fillinstacktrace(); // 18
    }
   }
   public static void
   main(string[] args) throws throwable {
    try {
     g();
    } catch(exception e) {
     system.out.println(
      "caught in main, e.printstacktrace()");
     e.printstacktrace();
    }
   }
  } ///:~
  
  其中最重要的行号在注释内标记出来。注意第17行没有设为注释行。它的输出结果如下:
  
  originating the exception in f()
  inside g(), e.printstacktrace()
  java.lang.exception: thrown from f()
      at rethrowing.f(rethrowing.java:8)
      at rethrowing.g(rethrowing.java:12)
      at rethrowing.main(rethrowing.java:24)
  caught in main, e.printstacktrace()
  java.lang.exception: thrown from f()
      at rethrowing.f(rethrowing.java:8)
      at rethrowing.g(rethrowing.java:12)
      at rethrowing.main(rethrowing.java:24)
  
  因此,违例堆栈路径无论如何都会记住它的真正起点,无论自己被重复“掷”了好几次。
  若将第17行标注(变成注释行),而撤消对第18行的标注,就会换用fillinstacktrace(),结果如下:
  
  originating the exception in f()
  inside g(), e.printstacktrace()
  java.lang.exception: thrown from f()
      at rethrowing.f(rethrowing.java:8)
      at rethrowing.g(rethrowing.java:12)
      at rethrowing.main(rethrowing.java:24)
  caught in main, e.printstacktrace()
  java.lang.exception: thrown from f()
      at rethrowing.g(rethrowing.java:18)
      at rethrowing.main(rethrowing.java:24)
  
  由于使用的是fillinstacktrace(),第18行成为违例的新起点。
  针对g()和main(),throwable类必须在违例规格中出现,因为fillinstacktrace()会生成一个throwable对象的句柄。由于throwable是exception的一个基础类,所以有可能获得一个能够“掷”出的对象(具有throwable属性),但却并非一个exception(违例)。因此,在main()中用于exception的句柄可能丢失自己的目标。为保证所有东西均井然有序,编译器强制throwable使用一个违例规范。举个例子来说,下述程序的违例便不会在main()中被捕获到:
  
  //: throwout.java
  public class throwout {
   public static void
   main(string[] args) throws throwable {
    try {
     throw new throwable();
    } catch(exception e) {
     system.out.println("caught in main()");
    }
   }
  } ///:~
  
  也有可能从一个已经捕获的违例重新“掷”出一个不同的违例。但假如这样做,会得到与使用fillinstacktrace()类似的效果:与违例起源地有关的信息会全部丢失,我们留下的是与新的throw有关的信息。如下所示:
  
  //: rethrownew.java
  // rethrow a different object from the one that
  // was caught
  
  public class rethrownew {
   public static void f() throws exception {
    system.out.println(
     "originating the exception in f()");
    throw new exception("thrown from f()");
   }
   public static void main(string[] args) {
    try {
     f();
    } catch(exception e) {
     system.out.println(
      "caught in main, e.printstacktrace()");
     e.printstacktrace();
     throw new nullpointerexception("from main");
    }
   }
  } ///:~
  
  输出如下:
  
  originating the exception in f()
  caught in main, e.printstacktrace()
  java.lang.exception: thrown from f()
      at rethrownew.f(rethrownew.java:8)
      at rethrownew.main(rethrownew.java:13)
  java.lang.nullpointerexception: from main
      at rethrownew.main(rethrownew.java:18)
  
  最后一个违例只知道自己来自main(),而非来自f()。注意throwable在任何违例规范中都不是必需的。
  永远不必关心如何清除前一个违例,或者与之有关的其他任何违例。它们都属于用new创建的、以内存堆为基础的对象,所以垃圾收集器会自动将其清除。
 
 
上一篇: runtimeexception的特殊情况    下一篇: 捕获所有违例
  相关文档
针对java移动设备的3d图形第2部分:m3g的保留模式 11-17
jsf实例:组件显示(隐藏)与数据排序 11-17
实战java用户界面本地化 11-16
java中关于xml的api惊鸿一瞥 11-16
j2se中的序列化的认识 11-16
servlet实现的代理服务器功能 11-17
JAVA基础:从.class文件中寻找类名 08-06
jdbc之接口技术 11-17
applet在ie浏览器中不能显示的解决方案 11-17
每个java初学者都应该搞懂的问题! 11-16
细述java技术开发规则--开发篇 11-16
使用java web start 和 jnlp技术来部署应用 11-17
经典java开发工具介绍(1):oracle internet developer 11-17
struts构建文件上传(7) 11-17
struts快速学习指南之一 11-17
用jdring设置类似cron的日程提醒 11-16
jbuilder 2005单元测试之慨述 11-17
使用collections 11-17
探讨java与ruby语言迁移时的安全性问题 11-19
java api之算法 11-16
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息