try catch 语句好不好?

2024-08-27 22:18
文章标签 try catch 语句 好不好

本文主要是介绍try catch 语句好不好?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


                                                                  try catch 语句好不好?


      在ITOOjava5.0代码走查中,有一个 细节,Try  catch 不是很建议用,如果是用了,又是为什么呢,对于这个进行

一个小的总结。


  一句话解释

  

      try catch机制可以非常好。觉得try catch 不是很好的,可能是还没有发现她的好!



二、详细解释
   1.程序要健壮,必须要设计报错机制。
     最古老,也是最常见的,比如:

bool CreateFile( );
//如果创建文件失败就返回false,否则返回true。


//如果创建文件失败就返回false,否则返回true。
这种报错方式,显然不好。因为它没有给出产生错误的具体原因。


2.改进:一个函数或过程,会因为不同的原因产生错误,报错机制必须要把这些错误原因进行区分后,再汇报。
比如:

<span style="font-size:18px;">int CreateFile():
//如果创建成功就返回1.
//如果是因为没有权限,导致失败,返回-1。
//如果是因为文件已经存在,导致失败,返回-2。
//如果是因为创建文件发生超时,导致失败,返回-3。</span>

这样看上去,比【1】要好些,至少指出了比较具体的失败原因,但是,还不够。



    3.很多情况下,函数需要把详细的原因,用字符串的方式,返回:
<span style="font-size:18px;">class Result
{
....int State;//同【2】
....string ErrorMessage;//如果失败,这里将给出详细的信息,如果有可能,应该把建议也写上去。
}Result CreateFile();
//如果创建成功,返回的Result,State为1,ErrorMessage为null。
//如果是因为没有权限,导致失败,返回的Result,State为-1,ErrorMessage为"用户【guest】没有权限在【C:\】这个目录下创建该文件。建议您向管理员申请权限,或者更换具有权限的用户。"。
//如果是因为文件已经存在,导致失败,返回的Result,State为-2,ErrorMessage为"文件【C:\abc.txt】已经存在。如果需要覆盖,请添加参数:arg_overwrite = true"。
//如果是因为创建文件发生超时,导致失败,返回的Result,State为-3,ErrorMessage为"在创建文件时超时,请使用chkdsk检查文件系统是否存在问题。"。</span>


       4.我个人推崇上面这种方式,完整,美观。但是这种流程,容易与正常的代码混在一起,不好区分开。因此,Java、C#等设计了try catch这一种特殊的方式:
void CreateFile()
//如果创建成功就不会抛出异常。
//如果是因为没有权限,导致失败,会抛出AccessException,这个Exception的Msg属性为"用户【guest】没有权限在【C:\】这个目录下创建该文件。建议您向管理员申请权限,或者更换具有权限的用户。"。
//如果是因为文件已经存在,导致失败,会抛出FileExistedException,这个Exception的Msg属性为"文件【C:\abc.txt】已经存在。如果需要覆盖,请添加参数:arg_overwrite = true"。
//如果是因为创建文件发生超时,导致失败,会抛出TimeoutException,这个Exception的Msg属性为"在创建文件时超时,请使用chkdsk检查文件系统是否存在问题。"。

    可见,上述机制,实际上是用不同的Exception代替了【3】的State。


这种机制,在外层使用时:
try
{
....CreateFile( "C:\abc.txt" );
}
catch( AccessException e )
{
....//代码进入这里说明发生【没有权限错误】
}
catch( FileExistedException e )
{
....//代码进入这里说明发生【文件已经存在错误】
}
catch( TimeoutException e )
{
....//代码进入这里说明发生【超时错误】
}
对比一下【3】,其实这与【3】本质相同,只是写法不同而已。


5.综上,我个人喜欢【3】这类面向过程的写法。但很多喜欢面向对象的朋友,估计更喜欢【4】的写法。然而

【3】与【4】都一样。这两种机制都是优秀的错误处理机制。




6.理论说完了,回到正题,题注问:为什么不用try catch?


      解答:这是因为,有的人可能还不是很熟练,以及新手,他们可能这样写代码的:


<span style="font-size:18px;">void CreateFile( )
//无论遇到什么错误,就抛一个 Exception,并且也不给出Msg信息。
这样的话,在外层只能使用:
try
{
....CreateFile( "C:\abc.txt" );
}
catch( Exception e )
{
....//代码进入这里说明发生错误
}</span>


当出错后,只知道它出错了,并不知道是什么原因导致错误。这同【1】。


 以及,即使CreateFile是按【4】的规则设计的,但菜鸟在外层是这样使用的:
<span style="font-size:18px;">try
{
....CreateFile( "C:\abc.txt" );
}
catch( Exception e )
{
....//代码进入这里说明发生错误
....throw Exception( "发生错误" )
}</span>


   这种情况下,调用了这段代码,或者用户看到这个错误信息,也只能知道发生了错误,但并不清楚错误的原因。这

【1】是相同的。



    出于这些原因,可能新手以及用户,并没有想到,造成这个问题原因是熟练度不够,写代码图简单省事。他们却以 

为是try catch机制不行。



     所以,在这种情况下,肯定很多人觉得,还是不建议用try catch。




二 、经验总结:

        最好问清楚是那种语言。不同语言处理Try Catch的机制不一样,所以也会有不同回答。

 (1)对于C++:

        是不推荐用try catch的,它推荐使用Windows API那种HResult来返回错误情况,原因是try catch会在已有的代码

上面增加额外的cost, 这个额外的cost不是说只有throw exception的时候才会有,而是在try catch block里面的每一行

代码中都会有,这也是为什么他不建议你使用try catch最主要的原因。在Windows的源代码中,是没有任何try catch

的,全部用HResult来处理。


  (2)对于C#:

         try catch是建议使用的,C#设计的时候吸取的C++ try catch的教训,所以直接用Try catch包裹已有代码增加的

cost可以忽略不计,但是如果真的在代码运行过程中throw exception了,这个cost还是很大的。所以,在C#代码设计

中,throw exception基本上是你认为不会发生这种意外的情况下,否则,如果是常见错误,最好不要throw 

exception。

     比如Java, try catch也是建议使用的,我这个用的不熟,不过看它的说明,即使是throw exception的时候的cost也

很小。




三、在java语言中:

     其实通过上面的例子我们发现,不是不建议用.而是不应该滥用.


      这里《Effective Java》的有关异常的几个条目说的非常明白.建议题主去看一下.我这里就简单的搬运一下.部分原

文如下:

     只针对不正常的情况才使用异常 书中给出了一个例子
try {int i=0;while (true) {arr[i]=0;i++;}} catch (IndexOutOfBoundsException e) {}


  这是一个非常明显的错误,希望通过异常来中断循环而达到某种优化.其实不然.

  

     •JVM对异常的块中的代码几乎不做优化.

  

     •而且创建、抛出、捕获异常都是十分昂贵的


    •正常的遍历数组并不会造成冗余的边界检查,现代的JVM会做出优化



    避免不必要的使用被检查的异常


       “被检查的异常”是Java语言的一个很好的特性。与返回代码不同,"被检查的异常"会强迫程序员处理例外的条

件,大大提高了程序的可靠性。

 

        但是,过分使用被检查异常会使API用起来非常不方便。如果一个方法抛出一个或多个被检查的异常,那么调用

该方法的代码则必须在一个或多个catch语句块中处理这些异常,或者必须通过throws声明抛出这些异常。 无论是通

过catch处理,还是通过throws声明抛出,都给程序员添加了不可忽略的负担。


      适用于"被检查的异常"必须同时满足两个条件:第一,即使正确使用API并不能阻止异常条件的发生。第二,一旦

产生了异常,使用API的程序员可以采取有用的动作对程序进行处理。



   不要忽略异常, 有些程序员会写出下面的代码
<span style="font-size:24px;">try {
...
} catch (SomeException e) {
}
</span>


  空的catch块会使异常达不到应有的目的,异常的目的是强迫你处理不正常的条件。忽略一个异常,就如同忽略一

个火警信号一样 -- 若把火警信号器关闭了,那么当真正的火灾发生时,就没有人看到火警信号了。所以,至少catch

块应该包含一条说明,用来解释为什么忽略这个异常是合适的。



  小结:


       try catch是否建议使用要看具体语言,最重要衡量的标准就是它对已有的代码性能有多大的影响。但是

从它设计的角度就是为了处理一些意料不到的情况,但是因为当初引入的时候各种各样的原因,导致有些语言为了性

能,不推荐使用。

      

         BTW, try catch最好不要catch (Exception), 这样会吃掉不该吃的问题,比如C#中的StackOverflowException, 

OutOfMemoryException, NullReferenceException etc. 该crash的时候就应该让App crash, restart, 这也是保护你

service的一个好方法。






这篇关于try catch 语句好不好?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112932

相关文章

Python异常处理之避免try-except滥用的3个核心原则

《Python异常处理之避免try-except滥用的3个核心原则》在Python开发中,异常处理是保证程序健壮性的关键机制,本文结合真实案例与Python核心机制,提炼出避免异常滥用的三大原则,有需... 目录一、精准打击:只捕获可预见的异常类型1.1 通用异常捕获的陷阱1.2 精准捕获的实践方案1.3

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

MySQL中REPLACE函数与语句举例详解

《MySQL中REPLACE函数与语句举例详解》在MySQL中REPLACE函数是一个用于处理字符串的强大工具,它的主要功能是替换字符串中的某些子字符串,:本文主要介绍MySQL中REPLACE函... 目录一、REPLACE()函数语法:参数说明:功能说明:示例:二、REPLACE INTO语句语法:参数

MySQL ORDER BY 语句常见用法、示例详解

《MySQLORDERBY语句常见用法、示例详解》ORDERBY是结构化查询语言(SQL)中的关键字,隶属于SELECT语句的子句结构,用于对查询结果集按指定列进行排序,本文给大家介绍MySQL... 目录mysql ORDER BY 语句详细说明1.基本语法2.排序方向详解3.多列排序4.常见用法示例5.

Oracle查询表结构建表语句索引等方式

《Oracle查询表结构建表语句索引等方式》使用USER_TAB_COLUMNS查询表结构可避免系统隐藏字段(如LISTUSER的CLOB与VARCHAR2同名字段),这些字段可能为dbms_lob.... 目录oracle查询表结构建表语句索引1.用“USER_TAB_COLUMNS”查询表结构2.用“a

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

Mysql常见的SQL语句格式及实用技巧

《Mysql常见的SQL语句格式及实用技巧》本文系统梳理MySQL常见SQL语句格式,涵盖数据库与表的创建、删除、修改、查询操作,以及记录增删改查和多表关联等高级查询,同时提供索引优化、事务处理、临时... 目录一、常用语法汇总二、示例1.数据库操作2.表操作3.记录操作 4.高级查询三、实用技巧一、常用语