try,catch,throw—–C++

多使用几个 catch 即可捕获多种异常。

时间: 2018-12-18阅读: 1074标签: 异常前言

1.try,catch,throw:

try { } catch (SqlException) { } catch (ArgumentException) { } finally {
}

ECMA-262第3版引入了try
catch语句,作为JavaScript中处理异常的一种标准方式。基本的语法如下所示。但是在前端js代码中很少看到try
catch语句,并不是所以代码都需要加try
catch来作得不偿失的“保险”,下面来分析作为前端代码,哪些地方才需要真正加try
catch。

 try包含你要防护的代码 ,称为防护块.
防护块如果出现异常,会自动生成异常对象并抛出.

一、try catch语法

 catch捕捉特定的异常,并在其中进行适当处理.

try { //可能会导致错误的代码} catch (error) { //在错误发生时怎么处理}finally { //即使报错始终执行 }

throw可以直接抛出/产生异常,导致控制流程转到catch块.

二、try catch缺点1.try catch耗性能

2.重要观点: C++中异常是用对象来表示的,称为异常对象.

众所周知,js以一个大括号{}决定一个块级作用域,代码进入try catch的时候
js引擎会拷贝当前的词法环境,拷贝的其实就是当前 scope
下的所有的变量,这样消耗的性能是很大的,性能消耗与try
catch代码量以及变量成正比。

3.基本格式:

2.try catch捕获不到异步错误

try {    your code; }

尝试对异步方法进行try catch操作只能捕获当次事件循环内的异常,对call
back执行时抛出的异常将无能为力。

catch(T1 t1)    //T1可以是任意类型,int,char…

try { setTimeout(()={ const A = 1 A = 2 },0)} catch (e) { // 这里并不能捕获回调里面抛出的异常 console.log("-----catch error------") console.log(e)}

{ /*T1指定了你要捕捉的异常的类型,t1指定了异常
对象的名称,当有异常抛出,异常对象将被复制到t1
中,这样你就可以在本处理块中使用该对象,获取相关信息,进行适当处理;*/}

3.try catch可能会导致报错点更模糊

catch(…)    //…是捕捉任意类型的异常.

try
catch语句中报错直接到catch中处理,而浏览器控制台看不到报错信息。但很多人并没有在catch中抛出报错信息,或改写成自己随意写的报错文言,这样其实不如直接看浏览器原生的报错修改bug更方便。

/*某个catch执行完,就跳转到这里继续执行. 在没有使用C++异常处理的情况下,如果在此之前出现异常,则异常点以下的其他代码不会被执行从而造成问题.请考虑在这里放置:
delete
pobj1;如果不使用用try,catch机制,内存泄漏是必然的,因为出现问题后,执行流程无法跳转到这里.
*/

三、try catch总结

/*说明: try{}之后可以跟任意个catch块.
发生异常后,会生成临时的异常对象,进行一些自动处理之后,程序
流程跳转到后面的catch(),逐个检查这些catch(),如果与catch()
中指定的类型一致,则将对象拷贝给catch参数中的对象,
接着执行该catch块中的代码,然后跳过其他所有剩下的catch,
继续执行后续的代码.
上面所说的自动处理指的是堆栈回退,说白了就是为函数中的局部对象调用析构函数,保证这些局部对象行为良好.
*/

说了这么多try catch的缺点,有些小伙伴们就会奇怪到里那里用try
catch比较合适呢?

catch()的顺序通常按照:从特殊到一般的顺序: catch(Tsub o){} catch(Tbase
o){} catch(…){} 
如果第一个catch为catch(Tbase){},则它将捕捉其所有派生类的 异常对象. 
如果第一个catch为catch(…){},则其后的所有catch永远不可能 被执行.
重新抛出异常: 从上面的处理机制可以看到,只有一个catch可能被执行,
如果一个catch被执行,其他后续的catch就会被跳过了. 
有时候一个catch中可能无法完成异常的全部处理,需要将
异常提交给更高的层,以期望得到处理.重新抛出异常实现 了这种可能性. 语法: 
throw ; 空的throw语句,只能在catch中使用.    
它重新抛出异常对象,其外层的catch可能可以捕捉这个重新抛出的异常并做适当处理.

try
catch最适合处理那些我们无法控制的错误,如I/O操作,后端java读取I/O操作比较多比如读数据库,所以用try
catch比较多。前端可以用在上传图片或async await同步调接口。


async function f() { try { await Promise.reject('出错了'); } catch(e) { } return await Promise.resolve('hello world');}

1、基础介绍 try { //程序中抛出异常 throw value; } catch(valuetype v) {
//例外处理程序段 }
语法小结:throw抛出值,catch接受,当然,throw必须在“try语句块”中才有效。
2、深入throw:
(i)、程序接受到throw语句后就会自动调用析构器,把该域(try后的括号内)对象clean
up,然后再进 入catch语句(如果在循环体中就退出循环)。
这种机制会引起一些致命的错误,比如,当“类”有指针成员变量时,在
“类的构建器
”中的throw语句引起的退出,会导致这个指针所指向的对象没有被析构。解决方法:把指针改为类就行了,比如模板类来代替指针,在模板类的内部设置一个析构函数。
(ii)、语句“throw;”抛出一个无法被捕获的异常,即使是catch(…)也不能捕捉到,这时进入终止函数。
3、深入catch: 一般的catch出现的形式是: try{} catch(except1&){}
catch(except2&){} catch(…){} //接受所有异常
一般都写成引用(except1&),原因很简单,效率。
问题a:抛出异常,但是catch不到异常怎么办?在catch没有捕获到匹配的异常的时候,会调用默认的终止函数。可以调用set_terminate()来设置终止函数,参数是一个函数指针,类型是:void
(*terminate)()。

但是大部分前端代码处理都不怎么依赖环境也没有I/O操作,都是自己写的代码,在明明白白地知道自己的代码会发生错误时,再使用try
catch语句就不太合适了,所以慎用try catch。

4、try一个函数体,形式如下 void fun(type1,type2)
try----try放在函数体后 { 函数定义 } catch(typeX){}
这个用法的效果就相当于: void fun() {   try{函数定义} }
5、throw一个函数体,形式如下: void fun (); // 能抛出任何类型的异常 void
fun () throw(except1,except2,except3)                    //
后面括号里面是一个异常参数表,本例中只能抛出这3中异常,如 void fun ()
throw()  // 参数表为空,不能抛出异常
假设fun()中抛出了一个不在“异常参数表”中的异常,会怎么样?调用set_terminate()中设定的终止函数。然而,这只是表面现象,实际上是调用默认的unexpected()函数,然而这个默认的 
unexpected()调用了set_terminate()中设定的终止函数。可以用set_unexpected()来设置unexpected, 
就像set_terminate()一样的用法,但是在设定了新的“unexpected()”之后,就不会再调用set_terminater中设定的终止函数了。

来源:

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图