异常

应用程序开发——异常(异常分类、常见异常、异常处理、自定义异常) 异常分类:(Throwable:所有异常和错误的父类)●  Error:JVM无法解决的严重问题(JVM系统内部错误、资源耗尽等。一般不编写针对性的代码进行处理)●  Exception:编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理-----------------------------------------------------------------------... 阅读详情

转自:http://blog.youkuaiyun.com/lsm307742191/archive/2008/12/15/3515753.aspx

基本知识

程序做错误检查是必要的,通常我们可以通过返回值告诉客户有了错误,不过异常提供了更加方便的手段和丰富的信息。

当某处程序发现了错误,可以选择自己处理或者交给外部调用者处理,比如:

void Func(char* p)

{

if(p==NULL)

{

throw std::invalid_argument(“p is NULL”);

}

}

 

而调用者可以选择拦截该异常对象或者放过,交由更外层的逻辑处理。

try

{

Func(NULL);

}

catch(std::invalid_argument const& e)

{

cout<<e.what()<<endl;

throw;

}

这个例子中,调用者将异常对象拦截,显示出错误信息,然后使用throw继续抛出该异常对象,像接力棒一样。如果不写throw语句,异常到此就终止了。

在一个情况复杂的大型系统中,异常对象的灵活处理方式提供了很大的方便,同时异常本身就是一个对象,对象能够提供的丰富信息是旧式的返回错误值不具备的。

异常的传播方式和调用链相反,这称之为栈展开(stack unwinding)。在异常发生的地方,编译器必须完成以下的事情:

如果throw发生在try区块中,寻找匹配的cath语句,如果找不到,则当前函数立刻返回,并往上一级调用函数中寻找匹配的catch语句,该动作将一直重复直到有合适的catch语句出现。如果一直到最后都没有发现合适的catch语句,系统将调用terminate,而默认情况下,terminate将调用abort结束整个进程。

异常对象可以使某个class,也可以模板类型,也可以是预定义类型,下面的代码仍然正确:

 

void f()

{

throw 3;

}

 

int _tmain(int argc, _TCHAR* argv[])

{

try

{

f();

}

catch(int e)

{

cout<<e<<endl;

}

return 0;

}

当我们在一个函数中throw 一个对象的时候,如果该对象是创建在该函数中的栈上,编译器会将该对象拷贝一份副本,放到某个特定的区域,保证当外部程序使用catch语句时可以访问到该副本,所以这种情况下异常对象的类型必须提供拷贝构造函数或者是预定义类型。下列代码故意禁止了A类的拷贝构造函数,因此程序无法正确链接到拷贝构造函数。

 

class E

{

public:

E(){}

void print() const

{

cout<<_i<<endl;

}

private:

int _i;

private:

E(E const& e);

};

 

void f()

{

E e;

throw e;

}

 

int _tmain(int argc, _TCHAR* argv[])

{

try

{

f();

}

catch(E const& e)

{

e.print();

}

return 0;

}

error LNK2001: unresolved external symbol "private: __thiscall E::E(class E const &)" (??0E@@AAE@ABV0@@Z)

我们必须意识到,通过throw语句抛出异常对象的时候,拷贝一次对象是必须付出的成本。除非我们抛出的是一个对象指针。但是这种方式通常并不推荐。请看下面的代码:

 

class E

{

public:

E(){}

void print() const

{

cout<<_i<<endl;

}

private:

int _i;

private:

E(E const& e);

 

};

 

void f()

{

throw new E();

}

 

int _tmain(int argc, _TCHAR* argv[])

{

try

{

f();

}

catch(E * p)

{

p->print();

//.....

delete p;

}

return 0;

}

如果delete p语句执行之前,出现了新的异常,该语句将没有机会被执行,内存泄露。作为弥补的办法,我们修改catch中的代码。

catch(E * p)

{

auto_ptr<E> sp(p);

sp->print();

//.....

}

但是或许我们的异常是被别的程序员拦截的,假如他们没有意识到这个问题的严重性,内存泄露就有可能发生。异常毕竟代表系统的错误,而不是程序逻辑的一个常见分支,因此发生的概率较低。在较安全使用和效率之间折衷的做法,参见下面的代码:

 

void f()

{

throw E();

}

 

int _tmain(int argc, _TCHAR* argv[])

{

try

{

f();

}

catch(E const& e)

{

e.print();

}

return 0;

}

我们使用了 throw E()代替 E e();throw e;两句话,编译器通常当看到没有具体名字的临时变量会采取一些优化措施。同时,我们在catch语句中参数类型使用的是E const& ,这样会避免在将异常对象传递给chtch块时的一次无谓的对象拷贝。

由于异常是非常严重的错误,所以我们假定它发生的频率不高,那么一次对象拷贝通产不会造成太大的影响。要避免的是滥用异常,如查找字典程序不恰当的用抛出异常来表达找不到单词,这将对性能造成毁灭性的影响。

 

异常的成本

我们前面提到过,如果你使用throw语句抛出一个异常对象,无论你抛出的是局部变量还是全局或者静态变量,都会造成编译器拷贝一次副本,然后使用该副本在异常传播链中传递。除非你用异常对象的指针传递,通常这种做法不推荐。

如果你使用catch语句捕捉异常对象,请注意总是捕捉异常对象的引用,如果捕捉异常对象的话,会导致再一次的拷贝。

当你在catch块中试图继续传递异常对象的时候,请使用throw,而不是throw obj,后者回导致再一次的拷贝。

Scott Meyers在他的<<More Effective C++>>中说道,“如果使用try语句块,代码大约整体膨胀5-10%,执行速度也大约下降这个数。这是在假设没有任何exception被抛出的情况下”。“和正常的函数返回动作比较,由于掷出exception而导致的函数返回,其速度可能比正常情况下慢三个数量积”。

所以异常是用来表示错误的,我们首先要做的是区分什么是正常情况和错误。

异常的使用时机

不要在析构函数中使用异常

我们先来看下面的例子:

 

class E

{

public:

~E()

{

throw string("ok");

}

};

 

 

int _tmain(int argc, _TCHAR* argv[])

{

try

{

E e;

throw string("bad");

}

catch(...)

{

 

}

 

int x;

cin>>x;

return 0;

}

E类的析构函数中有一个抛出异常的语句,当_tmain函数的try块中执行到throw string(“bad”)时,try块所在的栈开始销毁,这时E的析构函数将调用,当执行到throw string(“ok”)语句时,C++编译器将直接调用terminate函数。真是非常的糟糕!

阻止析构函数中抛出异常

但是也许是析构函数的某个内在操作抛出了异常,怎么预防呢?比如:

class DBConn

{

public:

static DBConn create();//connect to db

~DBConn();
}

在DBConn析构的时候自动关闭与数据库的连接这种设计总是吸引着我们。但是,如果你使用的是某个数据库驱动程序的API Disconnect(),该函数的文档中说道,当执行错误时会抛出异常,怎么办?

使用try/catch语句在析构函数中处理可能发生的异常时必要的,但是如果抓到了异常如何处理呢?写日志,然后终止异常的传播?写日志,然后继续throw?写日志,然后终止程序?第二种肯定不行,我们就是要阻止异常从析构函数中传递。第三种有时候可以,因为可能没有其他办法继续下去。第一种做法看上去不错,但是从调用者的角度,除非他尝试着查看日志,否则他不知道发生了什么事情?用全局变量来告诉调用者错误信息?怎么看上去不够面向对象呢?

Scott Meyers提出了一个算比较好的解决方案:

增加一个close函数和bool closed变量。

class DBConn

{

public:

static DBConn create();//connect to db

~DBConn()

{

if(!closed)

{

try

{

close();

}

catch(...)

{

//记录错误日志,调用abort或者什么都不作(异常到此停止传播)
}

}

}

close();

private:

bool closed;

}

close函数负责关闭连接,析构函数中判断如果客户没有调用close函数,就调用close函数关闭连接。

析构函数中的catch块中的做法只是最后一道防线,应该总是鼓励客户显式调用close函数,这样当异常发生在close函数中时,客户可以自己决定如何处理。

构造函数中使用异常的注意事项

为什么有人想在构造函数中抛出异常?或许是因为他的构造函数认为某个输入参数不正确,不能构造对象,因此抛出异常强制客户处理错误信息。这样的人信奉错误应该在它发生的地方尽早被发现,而不是拖到当用户调用某个成员函数的时候。我就是。

但有时候并不是故意抛出异常,而是构造函数本身内部执行了复杂的初始化逻辑,突然某个函数(也许是别人提供的)抛出了异常,这个时候要注意前面已经被初始化的对象能够正确释放内存。

如果是在构造函数的初始化列表中发生了异常,怎么办呢?下面介绍一种用法:

class E

{

public:

E()

{

throw string("ok");

}

};

 

class B

{

public:

B();

 

private:

char* _p;

E _e;

};

 

inline B::B()

try:_p(new char[100]),_e()

{

}

catch(const string& e)

{

delete _p;

}

 

 

int _tmain(int argc, _TCHAR* argv[])

{

try

{

B b;

}

catch(string const& str)

{

cout<<str<<endl;

}

int x;

cin>>x;

return 0;

}

这是比较少见的用法,try在初始化列表的前面,并且在函数体后面加上catch块。本例目的是回收_p指向的自由存储的100字节空间。请回答,如果不用考虑演示try用法的需要,有没有更优雅的做法?

优先使用异常报告错误

这是C++标准委员会对于C++异常的基本态度。因为异常会强制用户捕捉,而不像返回值可以不检查;因为异常是自动传播的;有了异常处理,就不必在控制流的主线中加入错误处理和恢复代码,使得主线逻辑更易理解和维护,当然也美观;构造函数和操作符而言,异常是优先考虑的方案。特别是构造函数,它根本没有返回类型。

性能通常不是异常处理的缺点,在不发生错误的情况下,不会带来多大的开销。问题是你必须正确识别什么是错误情况,从而避免不必要的频繁抛出异常的情况,而不是杜绝使用异常。

这实际上牵涉到错误处理的设计问题。是的,在设计阶段考虑错误是必须的,遗憾的是很多系统设计在这方面都相当草率。

错误设计要考虑:

  1. 哪些情况属于错误---定义错误的范围

观察代码最基本的执行单元—函数,错误大体可分为三类:

a)违反或者无法满足前条件

比如参数正确性(参数越界,指针是否为空)或某个状态约束,这种情况可以使用invalid_argument异常

b)无法满足后条件

比如函数想返回一个值,但是却不能生成一个有效的返回值,这时应该根据原因抛出不同类型的异常

c)无法重新建立不变式

对象成员的值和由成员所引用的对象的值汇集在一起就称为这个对象的状态。使一个对象的状态定义良好的性质就被称为它的不定式。

举个例子:

比如MyString类里有个char* _p成员变量,当构造函数执行成功后,_p指向一个长度`为_len的数组,并且_p[_len]==0。MyString的每个成员函数都必须保证重建这个不变式,直到最后销毁该对象。

  1. 错误的严重级别和分类

  2. 模块边界错误如何传递

这里不是指C++异常传递,这是C++代码都应该使用的内部机制。问题是模块边界如何传递错误,比如网络通信程序,比如com+程序等等。

  1. 哪些代码负责处理错误

  2. 错误如何处理?写日志或通知用户还是短信通知等等

 

     关于参数检查,我个人意见是,如果是指针参数,首先看看能不能改为引用,这样就不用检查指针是否为空。如果必须是指针作为参数,则面临两个选择,以断言来预防错误assert(p!=NULL)或者直接进行条件判断if(p!=NULL) throw invalid_argument(“”)。究竟该选哪一个呢?

     assert用来防止程序员的错误,比如将一个空指针传入函数,而不是防止逻辑错误。问题是函数的设计者怎么知道调用者会不会犯错呢?其实,关于究竟用哪一个,目前也没有看到统一的方法。标准C++中的string采用了不管,即两个方法都不用,对构造函数和operator+接收到的char const*指针根本就不检查,boost::shared_ptr使用if语句,发现错误就抛出异常。

     考虑到boost是目前c++世界里代码最优雅的模范,尽可能使用条件判断的方式。只有一种情况下例外,如果一个指针依次传递给多个函数,如果这个指针大多数情况下总是有效,但每个函数都作了条件判断的检查,性能开销是很大的,这时候,或者内部使用的函数就应该用if语句预防,外部调用代码不考虑检验,或者调用代码负责检验,内部函数改用assert。这真是一个没有绝对答案的问题。

    这里我的经验是,如果我写一个函数,我会在参数校验上使用if语句,并在异常规格的注释说明中明确告诉别人我会抛出异常,如果有文档说明就更好了。调用者根据我的代码或者文档来决定是否再做校验,在性能和稳定性上自己平衡。写一个函数并不容易!

 

    当我最近写一个视频文件的断点续传程序时,我主要会碰到下面这些错误:

1)函数错误,主要是参数不正确的错误

2) 网络错误,主要是连接中断

3) 文件操作错误,比如读写文件,打开文件,浏览文件夹等操作的错误

4) 网络字节流解码错误

这些错误不属于程序逻辑的正常分支,因此适合用异常来表达,由于有些异常类别标准c++库中并没有合适的,我自己定制了一些异常类别,他们都是从标准异常类中派生下来的,并作了适当的功能扩展,为了方便以更好的格式将错误信息写到日志中去。这些错误我没有分严重级别,只进行了类别的划分,以便进行不同的处理。

   我的程序模块和调用者之间通过事件机制来通知发生了上面几种严重的错误。面对网络错误,主要是重新建立连接来解决,文件错误将会导致跳过错误文件发送其他文件。字节流解码错误会导致重新传送该文件。对于一个有经验的程序设计者,错误设计是一个展示其设计水平的重要方面。

标准异常

标准C++中为我们准备了异常的体系结构,当我们创建自己的异常对象时,应该总是先考虑一下标准异常类。

 

最顶层基类是exception,提供了what()虚函数用来描述错误:

virtual const char* what() const throw()。

通常如果你想要编写自己的异常类,比如MyException,你应该从exception的子类中选择一个派生。

异常规格

异常规范是C++标准委员会那些大师们的失败的作品。我们现在可以看到标准c++库中采用了异常规范,但是最新的boost库已经使用//throw ()代替throw。

以下几点原因:

  1. 异常规格导致性能降低

有些编译器会自动拒绝将有异常规格的函数进行内联;有些编译器根本不能很好的基于异常相关的信息进行优化,对于这些编译器,即使函数体内的代码清清楚楚的表明不可能抛出任何异常,它们还会在里面加上try/catch块

  1. 当违反了异常规格,无计可施

如果一个函数void Func() throw (A,B,C)的异常规格告诉你它只能抛出A、B、C三种类型的异常,万一在Func内部抛出了一个D类型的异常,编译器将通过生成try/catch块来处理这种情况:

void Func()throw (A,B,C)

{

try

{

....

}

catch(A)

{

throw;

}

catch(B)

{

throw;

}

catch(C)

{

throw;

}

catch(...)

{

std::unexcepted();

}
}

你可以通过调用std::set_unexpected来设置自己的处理函数,unexcepted函数将会调用你的函数,问题是这些函数没有任何参数,一个全局无参的函数怎么处理各种情况,也许有好多违反了异常规格声明的函数在等着依赖这个函数解决问题呢?答案是无计可施,通常只能调用terminate了事。

  1. 浅陋的类型系统

异常规格可以加到函数上,并且成为函数的类型的一部分,但是如果你试图在typedef语句中使用异常规格,是不允许的。

void f() throw (A,B);//ok

typedef void (*PF)() throw (A,B);//语法错误

void (*PF)() throw(A,B);//去掉typedef就可以

这个行为和C++类型系统的其他部分不一致。

异常安全

异常安全现在来看是个新鲜的高级主题,但是今后将成为必备的基本技术。我们先看看异常安全的定义:

当异常抛出时,带有异常安全性的函数将不泄漏任何资源,不允许数据败坏(如果是成员函数,通常意味着对象的状态不能被破坏)。

异常安全程度由高到低有三种:

  1. 承诺不抛出任何异常

  2. 保证即使抛出异常,程序状态回到执行函数前(事务操作)

  3. 保证即使抛出异常,程序状态仍然处于有效状态

在前面我们介绍过,防止泄露资源的做法是使用auto_ptr等智能指针或者自己封装一些类。要实现第二种程度的异常安全有一种做法叫作copy and swap.就是在成员函数的实现中使用先将对象拷贝一份,然后在副本上操作,当操作完成后,和当前对象交换。这种做法需要结合pimpl技术。

 

异常安全是个重大的话题,以至于引发了1997年互联网上C++世界长达几个星期的讨论,

也是导致Herb Sutter写出<<Exceptional C++>>的直接原因。异常安全涉及到很多复杂的技术,我这里只能介绍上述一些基本概念,如有兴趣,可以参考<<Effective C++>> 3th、<<Exceptional C++>>、<<Exceptional C++ Style>>。

异常检测中的三种异常:点异常、上下文异常、集合异常 文章目录直观解释点异常上下文异常集合异常Reference 直观解释 异常检测问题遇到的异常可以分为三类,分别是点异常(Point Anomalies)、上下文异常(Contextual Anomalies)和集合异常(Collective Anomalies)。 一图胜千言,下面分别用一张图说明这些异常。 点异常 示意图如下,其中o1o_1o1​、o2o_2o2​属于点异常 上下文异常 示意图如下,其中t2t_2t2​处属于上下文异常 集合异常 示意图如下,箭头所指的红框区域属于集合异常 Refer 阅读详情

相关推荐

Multisim14安装失败?手把手教你彻底清理残留文件(附专用卸载工具)

本文针对Multisim14安装失败问题,提供了一套从根源解决的完整方案。文章详细分析了安装失败的三大元凶——文件残留、注册表残留和隐藏组件,并手把手指导用户使用专用卸载工具进行标准化清理,再结合手动深度清理文件系统和注册表,最终实现彻底卸载和完美重装,有效解决Multisim14安装问题。

weixin_29179311的博客 317

九异常

基本知识程序做错误检查是必要的,通常我们可以通过返回值告诉客户有了错误,不过异常提供了更加方便的手段和丰富的信息。当某处程序发现了错误,可以选择自己处理或者交给外部调用者处理,比如:void Func(char* p){if(p==NULL){throw std::invalid_argument(“p is NULL”);}}而调用者可以选择拦截该异常对象或者放过,交由更外层的逻辑处理...

152

若依框架-实现管理端与用户端的不同页面布局

我们现在要做的是:管理员登录时展示后台管理端,普通用户登录时展示我们自己写的页面。所以我们可以用v-if来判断登录用户的角色,如果用户角色包含admin,说明是管理员,渲染管理端相关组件,否则渲染用户端组件。不过若依作者的本意还是想退出系统后清空角色信息,所以为了保险期间,我们可以在退出系统后,延迟2秒,再单独清空角色信息。当我们登录管理端后,再退出登录,会有那么一瞬间渲染用户页面,然后才是回到登录界面。这个时候,前端检测到角色信息为空,不包含admin,于是就会渲染用户页面。用来延迟 2 秒执行。

m0_74462339的博客 1566

Exceptional C++ Style之13

第13条 对异常规格的实际考虑      令人遗憾的是,我没有在实际代码中看见一行异常规格。typedef不支持异常规范。对虚函数来数,派生类对异常规范比基类更加严格。      异常规格常常是个善意的谎言,说这句话的时候,我其实有点疑惑,真的是善意?有时候可能叫做玩忽职守,或者什么其他的,但是这个地方真的是个问题。我完全认为这可能成为一个空头的承诺。      事实上,不要为函数加上

李永亮的专栏 833

图像去雾新思路:手把手教你复现DEA-Net中的“细节增强卷积”与PyTorch实现

本文详细解析了DEA-Net中的'细节增强卷积'(DEConv)与PyTorch实现,通过多分支差分卷积和重参数化技术,显著提升单图像去雾效果。文章从数学原理到代码实现,手把手指导复现这一创新架构,帮助开发者在保持轻量化的同时实现41dB以上的PSNR指标,适用于自动驾驶、遥感监测等关键领域。

weixin_30323631的博客 506

达芬奇Pro开发板硬件验证全流程指南

FPGA开发板硬件验证是嵌入式系统可靠性的基石,其核心在于理解SoC启动时序、IO资源映射与高速接口物理层约束。基于Xilinx Zynq-7000异构架构的开发平台,需围绕电源完整性、时钟稳定性、信号完整性及软硬协同启动链路展开分层测试。技术价值体现在规避量产失效率、支撑高可靠工业控制与实时图像处理等场景。典型应用涵盖千兆以太网通信验证、DVP摄像头与RGB LCD显示链路调试、以及SFP+光纤接口PRBS误码率测试。本文聚焦达芬奇Pro系列开发板,深入解析JTAG下载、QSPI Flash重烧录、RGM

weixin_42453228的博客 126

【C++】异常处理机制(对运行时错误的处理)

我们在编写程序的时候不可避免地会造成一些错误,有些错误是编译器可以帮我们找出并纠正的,而有些错误则需要我们自己自行处理。编译器负责静态检测,只能检查代码中明显的语义和语法错误,对于运行时的错误处理则需要我们设置适当的错误处理机制。

谁在夜里看海.的博客 3862

OceanBase迁移平台OMS企业版部署

OceanBase迁移平台OMS企业版部署摘要: 本文档详细介绍了OceanBase迁移平台OMS企业版的部署流程,包含环境准备、OAT部署管理、MetaDB部署等关键步骤。

Sebastien23的博客 523

C++11 noexcept 关键字用法学习

ow 关键字除了可以用在函数体中抛出异常,还可以用在函数头和函数体之间,指明当前函数能够抛出的异常类型,这称为异常规范,有些教程也称为异常指示符或异常列表。请看下面的例子: double func1 (char param) throw(int); 函数 func1 只能抛出 int 类型的异常。如果抛出其他类型的异常,try 将无法捕获,并直接调用 std::unexpected。 如果函数会抛出多种类型的异常,那么可以用逗号隔开, double func2 (char param) throw(int,

weixin_45032957的博客 2314

2024年广东省职业院校技能大赛“区块链技术应用”任务书—区块链应用系统开发参考答案

摘要 本文档提供了2024年广东省职业院校技能大赛"区块链技术应用"项目中区块链电子签章前端功能开发的参考答案。主要内容包括:1)注册页面开发,实现身份证号码双向绑定和注册请求发送;2)登录页面开发,实现用户认证、状态保存和页面跳转;3)个人印章页面开发,实现注销功能和印章信息展示。每个任务均包含具体实现代码片段和功能测试要点,涵盖Vue.js框架下的数据绑定、axios请求处理和本地存储等关键技术点。

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 346

AutoSar实战营 - 总目录

欢迎大家来学习《AutoSar实战营》专栏,该篇为总目录,方便以后大家直接进入需要学习的文章。 ~正所谓独乐乐不如众乐乐 - - ~1, AutoSar之DaVinci开发环境2,BswM模块之Ecu State Handling1)读写DID功能 《AutoSar实战》读写DID之一:CDD准备 《AutoSar实战》读写DID之二:工具链配置 《AutoSar实战》读写DID之三:代码实现2)功能寻址 《AutoSar实战》禁止功能寻址

weixin_48498880的博客 3634

C++ day34 异常(三)异常规范,未捕获异常,意外异常,异常导致内存泄漏

文章目录异常规范(C++98添加,C++11已摒弃,不建议使用)异常规范的作用(正是这俩作用的鸡肋和难办使它失去了粉丝)C++11支持的特殊的异常规范:关键字noexcept(程序员的庄严承诺)异常被引发后可能出现的两种问题未捕获异常 uncaught exception示例意外异常 unexpected exception(C++11摈弃异常规范的另一理由)异常处理可能导致==内存泄漏==:解决办法是智能指针模板总结 异常规范(C++98添加,C++11已摒弃,不建议使用) exception speci

wulimmya的博客 1570

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java中的异常总结详解(异常类型、声明异常、抛出异常、捕获异常)

Java 异常解析前言 前言

YING—country的博客 3万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

异常-异常场景的测试

在功能测试中,测试人员主要关注的是功能是否能符合预期的正常运行,比如测试一个下单的流程,关注下单、购买、发货流程是否能一气呵成。但仅仅关注正常流程是不够的,在实际的使用场景下,会出现各种非正常的情况: 一些具体的需求需要通过业务特性挖掘: 如果是秒杀这样的高并发业务场景,那么需要考虑降级、并发。 依赖消息通知的业务,需要关注NSQ推送和消费相关的异常。 使用缓存的业务,需要关注缓存访问失败的情况,以及异常情况下数据一致性。 如果业务流程很重要必须要保证成功,那么需要关注是否有降级、容错、重试

Queen_xzx的专栏 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

java异常 — — 异常的处理

二、异常的处理 Java异常处理的五个关键字: try、catch、finally、throw、throws 2.1、抛出异常throw 在编写程序时,我们必须要考虑程序出现问题的情况。比如,在定义方法时,方法需要接受参数。那么,当调用方法使用接受到的参数时,首先需要先对参数数据进行合法的判断,数据若不台法,就应该告诉调用者,传递合法的数据进来。这时需要使用抛出异常的方式来告诉调用者。 在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。 抛出异常后: ① 创建一个异常对象。封装一些提示

mocoll的博客 1万+

浅谈Java异常及其编译时异常和运行时异常的区别

异常是程序编码和运行时经常发生的事件,了解异常有助于我们提高代码质量,增强系统的健壮性,这里总结一下载Java编程中,编译时异常和运行异常时的区别,并列举几种常见的异常,以供参考学习。

Feify博客 1万+

抛出异常和捕获异常的区别

抛出异常:如果程序中出现了异常,没有办法将具体的异常打印出来,不做任何处理 捕获异常:如果程序出现了异常,就能够详细的打印是什么原因导致了异常并且能够做出相应的处理,能够显示详细的Log 如果异常出现的话,会立刻终止程序,所以我们得处理异常: 1. 该方法不处理,而是声明抛出,由该方法的调用者来处理(throws)。 2. 在方法中使用try-catch的语句块来处理异常。 ...

qq_29090169的博客 1万+

【JAVA |异常】异常总结详解(异常类型、声明异常、抛出异常、捕获异常)

在 Java 中,异常处理是一种重要的编程概念,用于处理程序执行过程中可能出现的错误或异常情况。异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。

YKX0000的博客 2872

【Java】❤️认识异常、异常的基本使用、认识异常(异常详解)❤️

目录一、 异常的背景异常体系:**防御式编程:**异常的好处二、异常的基本用法**基本语法****关于异常的处理方式**抛出异常 一、 异常的背景 初识异常 我们曾经的代码中已经接触了一些 “异常” 了. 例如 除以 0 public static void main(String[] args) { System.out.println(10 / 0); } 算术异常: 数组下标越界 数组越界 int[] arr = {1, 2, 3}; System.out.println(

意愿三七 4万+

ioexception属于什么异常_Java异常

异常介绍程序运行时,发生不被期望的事情,它阻止了程序 按照程序员的预期正常执行,这就是异常。异常发生时,是任其自生自灭,立即退出终止,还是输出错误给用户?用函数返回值作为执行状态?。Java提供了更加优秀的解决办法:异常处理机制。异常处理机制能让程序在异常发生时,按照代码的预先设定异常处理逻辑,针对性的异常处理,让程序尽最大可能的恢复正常并继续执行,且保持代码的清晰。Java中的异常可以是函数中的...

weixin_39861624的博客 8638

oracle异常、异常捕捉以及异常处理

异常以及处理异常1、概念2、预定义异常1、两数相除,分母为0,捕捉并抛出异常2、值转换异常3、根据姓名查找员工的职位,可能会出现的异常有:没有个这员工,或者有两个或更多的人叫同样的名字。3、非预定义异常4、自定义异常5、课堂练习: 1、概念 异常是指PL/SQL程序在执行时出现的错误 在PL/SQL中的一个警告或错误的情形都被称为异常。提示:编译错误(主要指语法错误)不包含在内。 异常处理通常写在执行体的最下面,在所有执行语句之后以exception关键字开始异常处理 语法: Exception when

hey,欢迎浏览我的博客,希望能给你提供帮助。 8302

JAVA基础:异常与异常对象,抛出异常,自定义异常,异常处理,受检与非受检异常

我们可以自定义异常,来描述出现的问题自定义异常类 , 继承异常相关的父类(Throwable,Exception , Error)一般异常的名字就体现了错误的情况,可以在配合注释进一步说明/**当年龄小于0或大于150时,抛出这样的异常*/2.通过有参构造方法,为异常提供更为详细的描述信息(可选)super(msg);3.使用throw 抛出异常。

weixin_53755148的博客 1286

【java】认识异常,理解异常,掌握异常

文章目录 1️⃣异常的背景 1.认识异常 2.避免异常的两种方式 2️⃣异常的基本用法 1.基本语法 2.多个 catch 块 3.使用共同父类 Exception 捕获异常 4.关于异常的错误输出 5.关于异常的调用链 6.关于 finally 代码块 7.使用 try 回收资源 8.一组关键字:throw 和 throws 9.异常处理流程总结 3️⃣异常体系结构 受查异常 4️⃣自定义异常类

Welcome to my blog. 1071

什么是异常?如何处理异常?

到底神马是异常?如何处理异常? 异常的概念 异常的体系结构 Java 异常的处理机制 异常处理的基本语法 异常链 自定义异常 总结 异常的概念 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出java.lang.ArithmeticException的异常。 异常发生的原因有很多,通常包含以

Anonymous_GL的博客 5156

声明异常,抛出异常,异常的简单总结

声明异常声明异常自定义异常若是有多种类型的异常匹配,则异常匹配的顺序总结: 如果在一个方法体中抛出了异常,如何通知调用者? 声明异常 方法有两种: 方法1:调用者处理异常:通常在方法后面加throws Exception 方法2:调用者继续声明异常(下一个接收的人在处理) public static void main(String[] args) throws Exception { //...

qq_41969892的博客 3999
上一篇: 使用异常和返回值,Exception and Error dispose
下一篇: Nagle算法TCP_NODELAY和TCP_CORK
UU_Yang
博客等级 码龄23年 926粉丝 213原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值