说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

细微之处见真章 为什么要在try-catch-finally里加大括号

HTML文档下载 WORD文档下载 PDF文档下载
相信每个程序员对try-catch-finally都不陌生,并且都知道它是用来处理异常的。那么你是否思考过,在if这些语句里不使用大括号编译器即可解析,可是为什么在try-catch-finally里就必须要使用大括号呢?

用C语言开发的程序员通常会使用if、while、for等组建一条语句或者是一个代码块。

  1. if (x)  
  2.   M(); 
  1. if (x)  
  2. {  
  3.   M();  
  4.   N();  

然而,语言设计者好像对此并不关心。像if、while、for等这些可以作为单独的一条语句,并且被大括号包围起来的部分也可以作为单独的代码块。

无论我们对语法进行怎样的思考,try-catch-finally肯定与if等语句是不同的。try-catch-finally需要一个支撑块(braced block)。

在我们深入try-catch-finally之前,先让我们换换思绪,来思考下面的问题。明确的循环结构(looping structures):

  1. while(A())  
  2.   while(B())  
  3.     C(); 

虽然没有大括号,但是内部while语句与外部while进行了很好地组合,所以没有括号也不影响阅读与理解。但如果把这种情况应用到if语句上,就会遇到著名的“dangling else ”问题。

  1. if (A())  
  2.   if (B())  
  3.     C();  
  4. else 
  5.   D(); 

好吧,请问这样的缩进正确吗?else D()是对应内部的if还是外部的if呢?

答案当然是与内部if相匹配的,else与最近的if语句相匹配(就近原则)。编程语言中空格并不重要,但在阅读代码时常常会因为错误的缩进格式而导致理解错误。在C或者C++中我也看到写的很糟糕的宏,并且导致了“dangling-else”问题。

在语言中添加try-catch-finally,设计者希望避免“dangling-else”问题。假设如果在try、catch或finally后可以插入任意行代码,而不是放置一段代码块,那么对于这样的代码片段,你会如何解释呢?

  1. try 
  2.   try 
  3.     A();  
  4.   catch AException  
  5.     B();  
  6. catch BException  
  7.   C(); 

不禁要问,这样的缩进正确吗?B()是受保护的?我们是否应该换种方式编写呢:

  1. try 
  2. {  
  3.   try 
  4.   {  
  5.     A();  
  6.   }  
  7.   catch AException  
  8.   {  
  9.     B(); // protected by the outer try  
  10.   }  
  11. }  
  12. catch BException  
  13. {  
  14.   C();  

难道上面的也有问题?

  1. try // try without associated catch!  
  2. {  
  3.   try 
  4.   {  
  5.     A();  
  6.   }  
  7.   catch AException  
  8.   {  
  9.     B(); // not protected  
  10.   }  
  11.   catch BException  
  12.   {  
  13.     C();  
  14.   }  

不要试图提出规则来消除这些模棱两可的语法解析,而最好的做法就是使用大括号——可以轻易地避免这种歧义。

有趣的是,从语法角度来看,try代码块完全没有必要。简单地说,任何块都可以跟随着catch代码块或者finally块, try块可以作为隐式代码块。这是一个冗余让代码更可读的典型例子。try关键字可以提醒读者,说明该段控制流需要处理一些异常信息。

此外,分享一个有趣的信息。在最初设计C#语言时,是没有try-catch-finally的,只有try-catch和try-finally。如果想编写try-catch-finally,你还得这样做:

  1. try 
  2. {  
  3.   try 
  4.   {  
  5.     A();  
  6.   }  
  7.   catch AException  
  8.   {  
  9.     B();  
  10.   }  
  11. }  
  12. finally 
  13. {  
  14.   C();  

语言设计者意识到这是种常见的模式并且是不必要的冗长,所以他们允许语法糖消除外部多余的try。但是C#编译器生成的代码正如你上面编写的嵌套一样,因为在CIL层中是没有try-catch-finally。另外,在C#中,if、while等并不是个单独的局部变量声明。

来自:Why are braces required in try-catch-finally?

向Facebook看齐,Twitter收购Android屏幕待机应用开发商Cover 绝对的超现实!Jaunt打造360°全景VR电影 Unite China 2014课程解析:行业解决方案专场免费开放 Manhattan,Twitter规模的实时、多租户分布式数据库 Ceph浅析(中):结构、工作原理及流程 孙元浩:基于Spark引擎的高速内存分析和挖掘工具应用 腾讯私有云背后的团队,品高要做企业云计算的产品经理 撼动企业应用架构的十大技术趋势 Airbnb的管理之道:产品设计的点评策略与技巧 Windows 8.1 Update 1的下载地址和八点须知 《近匠》棱镜:手游渠道SDK平台的技术历程 OpenSSL究竟为何物,为何它的影响力如此之大? Redis大冒险:如何跳出SQL这个坑 【走近院士】张尧学:基于透明计算的云操作系统 微软转型之路:从Build 2014开始 大势所趋 HTML5成Web开发者最关心的技术 从火种到核心,浅析Hadoop大数据用户的演变 搭建高可用的MongoDB集群(上):MongoDB的配置与副本集 软硬件协同创新,共建未来数据中心 优秀Unix管理员的七个习惯 2014Unity亚洲开发者大会倒计时 干货内容日程汇总 TIOBE 2014年4月编程语言排行榜:Perl跌至历史最低点 Hadoop集群环境下网络架构的设计与优化 CloudFoundry架构优化:NATS集群化方案 Dropbox推独立应用,公司估值已达100亿美元 【走近院士】梅宏:云计算时代软件技术发展需求和挑战 云计算战争:OpenStack vs. VMware Cortana与Siri、Google Now的较量:支持功能更多 代码面试最常用的10大算法 “颠覆医疗” 时云医疗推三款硬件产品 华为章宇:如何学习开源项目及Ceph的浅析 求救!!!会不会仅仅是病毒的问题? compute 字段在报表中的应用问题?在线等待! 高分相送,c++ builder中使用ocx控件 关于listview与数据库的问题,请大家帮我看看程序出错在哪?谢谢!! 高手请进!! 高手请进!! 关于数据库问题 高手请进!! 静态成员变量是全局变量吗?我能够在一个模块的几个不同文件中声明同名的静态成员变量吗? 一个奇怪的问题——ADO连接数据库 还是文件上传的问题~~ 怎样取得水晶报表的总页数? 现在还有多少在做lotus开发的程序员啊?有没前途,这东西? 用VB怎样调用SQL的计划任务 Help!Help!关于在application中(不是applet)用MediaTracker读图片的问题,高分酬谢。 请高手指点高程软件工程部分哪些书比较好啊! 当程序与远程数据库服务器建立连接后断网了,怎么能让程序自动再建立连接?谢谢 关于tatabto控件的问题!! 请问怎么样让NetMeeting ActiveX 控件自动接受呼叫? 在网关上修改通过的数据包,要求增添一些数据,请问大家有什么方法,要注意什么问题? 我原来有个ucap.jar包,把它拷到和notes.jar包同一个目录,代理中import不进来。请问各位大虾要不要设置classpath,怎么设置? 流场的可视化 这样的模板为什么不工作?? 请问这是什么错误!!各位帮我解决一下! 请问怎么样让NetMeeting ActiveX 控件自动接受呼叫?帮帮小妹吧 hellogzz,我就这80分,给你了 请问怎么样让NetMeeting ActiveX 控件自动接受呼叫? 有关form的菜菜问题,求助!!! 在存储过程中如何进行字符的运算 如何从表中随机选择一条记录? ?急救,在线等候!delphi怎么实现可以在word里面通用的报表??高分 Norton 服务器版怎么样?是否服务器升级病毒库后客户端可以从服务器上直接升级呢? 如何采用触发的方式接受串口消息,并将消息内容转化成字符串型? 各位高手,如何针对不同尺寸和分辨率的屏幕设计软件界面? 我ADVGRID6的控件组,在DLEPH7下通不过,总是说缺.PAS文件,其实它已经存在!为什么... 重分悬赏2000PROFESSION下配置PHP+MYSQL的方法。 关于editmask 请教关于串口控件——SPCOMM的简单问题 设计时数据模块突然无法打开,而运行时也报“无法连接sql server或网络连接失败”怎么办? 图形重绘的问题 关于对象字段的问题,up有分 做VC程序员半年来的感受和一年来的经历 CFile 请问如何使下面的窗口得不到焦点 其实我觉得这个社会上还是缺人才的。 CB编译错误谁能解决?(100分) c#中定义一个未知类型怎么做? 关于代理的疑难问题? 100分问一个天气预报的问题。 急!~~谁知道如何屏蔽网页中RealPlayer控件的右键菜单?哪位大虾回答对了马上给分!! 怎么将对话框Dialog显示在窗口最顶层,而不管有没有焦点? 上班盯电脑下班看电视:白领熬夜3天差彭丽媛出访备受追捧 惊叹第一夫人的外田朴珺以《中国合伙人》制片人的身份出嫩模苏梓玲亮相故意秀胸 网友鉴定:这10万人齐跳骑马舞!“鸟叔”再创吉尼蔡依林表弟当众打滚耍赖 视频被拍下网福州小朋友晒六一礼物:一张成龙亲笔签姚晨怀孕不忘捞金 挺大肚提名牌包包现芙蓉姐姐暴瘦照 转眼都成美女了《富春》林志玲宣传新片现场卖萌刘德华张静初来杭为《天机·富春山居图《封神榜》曝姜子牙白发造型 回应“最中国女模罗紫琳搭俄罗斯亿万富翁 海岛梁咏琪再登封面 曾因爱的勇敢而遍体鳞李宇春再登杂志封面 戛纳海边尽显俏皮黄晓明登封面称教主很忙:成功需要真诚杨幂登时尚杂志封面 展甜美呛辣本色《富春》主创做客 刘德华林志玲对戏害米兰达·可儿海滩写真 半裸出镜大秀瑜六六作品《宝贝》女主角孟丽清新私家美苟芸慧买衣专挑减价特价货 无惧地震将U16国少险胜缅甸张静初成金鸡女配热门E路同行 网络民生服务接受面对面测评石河子大排查大整治成效显著可采用相对开放立法框架华夏艺术中心将扩大法律援助受理范围坦荡做人谨慎用权郭声琨会见阿富汗总统国家安全顾问砍伤三护士嫌疑人落网细节披露国务院批准上海自贸区总体方案礼品不见了餐厅改名了标题新闻让每个人都感受到幸福东营督促整改火灾隐患63处中国公证协会新版门户网站开通我国国际储备资产增2036亿美元医务人员为钱所诱开虚假出生证王书金故意杀人强奸案二审宣判受贿百万副局长自首获刑7年半遵义消防“五微”打造平安校园
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘