CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Java >  J2SE / 基础类

JAVA里怎么处理异常的

楼主suyuan12345()2006-03-15 17:46:42 在 Java / J2SE / 基础类 提问

JAVA里是怎么处理异常的,耗内存吗 问题点数:100、回复次数:2Top

1 楼francis_zj(健健)回复于 2006-03-15 17:49:27 得分 100

 
  编码的艰难决择:应该这样做还是那样做?  
   
  性能讨论组中充斥着类似于这样的问题“我应该像大多数人那样编写代码,还是为了得到更好的性能那样编写代码?”一般专家会建议应该避免早期的优化,并且直到性能测试显示需要优化的时候才使用最优方法,但实际情况是我们每写一行代码都在做出会影响到性能的决定。  
   
  JavaRanch   上的一项讨论调查了确保类型安全的两种选择,一种是抛出异常,另一种是用   instanceof,并提出了“哪种方法更好”的问题。清单   1   和   2   显示了这两种方法。  
   
  清单   1.   使用   instanceof   来分支  
   
          Listing   1:   using   instanceof   to   branch  
              for   (int   i   =   0;   i   <   max;   i++)  
              {  
                    Object   obj   =   myVector.elementAt(i);  
                    if   (obj   instanceof   MySpecialClass)  
                    {  
                          //   do   this  
                    }  
              }  
   
  清单   2.   抛出异常来分支  
   
              for   (int   i   =   0;   i   <   max;   i++)   {  
                  try   {  
                      MySpecialClass   myClass   =   (MySpecialClass)myVector.elementAt(i);  
                      //   do   this  
                  }   catch   (ClassCastException   cce)   {  
                      continue;   //   for   loop  
                  }  
              }  
   
  提这种问题的危险之一是,当您想把问题浓缩成一个简单例子时可能会失去很多上下文。没有充分的上下文通常会把讨论弄得长而混乱,因为每一个阅读了问题的回答者都会用他们自己的上下文来联系问题。所有这种额外的上下文都会增添含义,这会把我们从问题的出发点转移出来。头脑里有了这些东西之后,就让我们来看能否从这一思路中找到的消息线索中筛选出某些真理来。  
   
  异常的特征  
   
  提起异常大多数开发者首先要说的就是它们很昂贵。如果您继续追问为什么它们很昂贵,最普遍的答案是我们需要捕获异常堆栈的当前状态。尽管这是开销的很大一部分,但通过列出异常的一些特征,我们可以知道这只是故事的开始。下面是异常的一些特征:  
   
  可以被抛出。    
  可以被捕获。    
  可以被程序化地创建。    
  可以被   JVM   创建。    
     被表示为第一级对象。    
  继承的深度从   3   开始。    
  由   String(和来自   1.4   的   StackTraceElements)组成。    
  依靠本机方法   fillInStackTrace()。    
   
  异常与其他对象的主要区别是异常可以被抛出和捕获。让我们从调查当异常被抛出时所触发的事件过程来开始我们的研究。  
   
  处理异常的开销  
   
  为了抛出异常,JVM   发出   athrow   字节码指令。athrow   指令引起   JVM   将异常对象弹出执行堆栈。然后   JVM   搜索当前执行堆栈帧来寻找第一个   catch   子句,这个子句可以处理该类的一个异常或者其超类的一个异常。如果在当前的堆栈帧里没有找到   catch   block,那么当前堆栈帧就被释放,异常在下一个堆栈帧的上下文中被重新抛出,如此这般,直到找到包含匹配的   catch   子句的堆栈帧,或者是到了执行堆栈的底部。最后,如果没找到适当的   catch   块,所有的堆栈帧都会被释放,线程在   ThreadGroup   对象有了处理异常的机会后被终止(参考   ThreadGroup.uncaughtException)。如果找到了适当的   catch   块,程序计数器会重置到那一块代码的第一行。  
   
  从这个描述中我们可以了解到处理一个抛出的异常是一个非常昂贵的主张。再看一看上面的异常特征清单。注意到除了   JVM   可以“本能地”创建一个异常外,其余剩下的开销与在任何其他第一级对象的生命周期中所引起的开销没有什么区别。    
   
  异常作为第一级对象的开销  
   
  现在回忆一下   清单   2。只有当强制转换失败的时候异常才被抛出。JVM   是如何处理它的呢?当一个应用需要进行强制类型转换的时候,一个   checkcast   操作就会被发出。这项操作只用于保证堆栈顶部的参数类型是预期的。如果不是预期的,它就会抛出一个   ClassCastException。  
   
  类型检查文雅的做法是使用如   清单   1   所示的   instanceof   操作符。checkcast   和   instanceof   的区别之一是后者会在堆栈的顶部保留   0   或   1   来表失败或成功。  
   
  instanceof   操作符遵循非常严格的一组规则来决定成功或失败。无论变量引用是不是   null、数组、接口或者类,规则都需要重视。一旦确定了变量的类型,就必须搜索另一边的合格操作数的层次,直到找到匹配的类型或者到达层次的结尾。在数组的情况中,基本元素的类型也也必须经过同样的审查。  
   
  除了这项开销外,一旦用了   instanceof,您就要在后面的代码里将对象进行强制类型转换。执行后继类型转换会导致   checkcast   字节码的执行。所以用于确定类型转换是否工作的逻辑可能会被重复(假设   JVM   没有优化额外的检查)。虽然如此,但因为使用   instanceof   操作符不需要创建新的对象,所以从内存资源和执行资源方面考虑,比起创建和处理异常来说它是廉价得多的操作。那么最初问题的答案就很明显了,对吗?  
   
  隐藏的风险  
   
  捕获   ClassCastException   同样存在隐藏的风险,也就是说我们可能会捕获从取代了“这样做”注释的代码中抛出的   ClassCastException。如果该代码在一些操作的中间抛出   ClassCastException,那么我们可以捕获到它,如果它来自对   MySpecialClass   的强制类型转换,并被忽略,就可能使应用程序处于不一致的状态。    
   
  动态调优  
   
  到目前为止,我们所做的只是评估了所提到的两种编码风格中每一种一次性执行的开销。现在我们需要了解代码将被执行的条件,以便确定应该使用哪种编码风格。  
   
  考虑迭代一个集合的情况,以了解实际花费的开销。如果集合包括同质的一组对象,并且将在的每一个对象上执行一个   instanceof   操作,过程会把不必要的开销强加在整个运行时间中。另一方面,如果集合包括异类的一组对象,那么我们使用   instanceof   操作会更好,而不会引起强烈的异常开销。    
   
  这种情况给了我们最优方法的最终线索:异常应该为异常的情况保留。在异常的情况下使用异常对性能来说是理想的;在无异常的情况下使用检查来避免抛出异常对性能来说也是理想的。  
   
  结束语  
   
  从所有这些我们可以看到,遵循最优方法(这里是指异常应该用于异常的情况下)可以产生更好的性能。有的时候我们需要全面考虑类似于这篇文章里所说的情景来决定最优方法到底是什么,以及最优方法在性能上考虑了什么和它的可选方案。但是现在不用担心过早地优化代码,我们以最好的编码实践结束,它有着适当的独立性能,也提供了优化的性能   ——   在两方面都是最好的。  
     
  Top

2 楼YuLimin(阿敏总司令:简单就是美—钻石闪闪您快结贴!)回复于 2006-03-16 18:10:15 得分 0

两位是否在演戏?Top

相关问题

  • 在JAVA异常处理的过程中,想知道最初异常是出在哪里,该怎么办?
  • 怎么处理这个异常???
  • 怎么处理一个异常
  • 异常处理?
  • 异常处理
  • 异常处理
  • 异常处理
  • java程序的异常处理中大的异常可否放在小的异常前头?
  • C++的异常处理与Java的不同和变通
  • 大家来谈谈JAVA中的异常处理!

关键词

  • 代码
  • 性能
  • 优化
  • 处理异常
  • 清单1
  • instanceof
  • 编写代码
  • 方法
  • 应该
  • 显示

得分解答快速导航

  • 帖主:suyuan12345
  • francis_zj

相关链接

  • CSDN Java频道
  • Java类图书
  • Java类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo