正确使用Exception异常对象

一、异常的构成

new Exception() 创建异常对象

throw 抛出异常对象(主要性能损耗位置)

try{}catch{} 捕捉异常对象

C#里面异常对象分为两个子类ApplicationException、SystemException,前者主要是提供给应用程序自定义的异常类,后者是提供给系统定义的异常类

二、如何使用异常

异常的正常逻辑是:由底层抛出,由高层处理

1、底层方法或者提供给其他人使用方法内的一些参数过滤或其它异常应该向上抛出

如(借鉴现成代码懒得写了):

public void InsertUser(User user)
{
     if(user==null)
    {
        throw new ArgumentNullException("参数user为null");
    }
    //调用Orm
}    

2、上层应该加上try{}catch{}来捕捉异常并处理

如:

try
{
    bll.InsertUser(null);
}
catch (ArgumentNullException e)
{
    LogHelper.Write(e.Message);
}

3、避免一些错误的异常处理方式

如(借鉴现成代码懒得写了):

/*
用异常验证用户输入
用户输入的合法性验证是属于业务逻辑的一部分,绝对不要用异常去处理,注意,是用户输入,所以这个经验仅限于表现层逻辑
*/
//典型错误1
try
{
    int i=int.Parse(textBox1.Text);
}
catch(Exception ex)
{
    alert(“不要输入非数字”);
}
//典型错误2
void ValidateInput(int i)
{
    if(i<0&&i>100)
    {
        throw new Exception("输入数据范围错误");
    }
}
/*
将异常交由给底层处理
这个错误在于完全不验证用户输入而直接把数据的验证抛向数据库,等待数据库报错来判断用户输入的正确性,这个是非常致命的错误,很多注入漏洞都是由此产生的
*/
//典型错误3
try
{
    string name=Request.QueryString["xx"];
     List<User> userls=User.QueryUserByName(name);
}
catch(SqlException ex)
{
}
/*
完全不用异常机制
产生这个错误肯定是一个非常脑残的决定造成的。不过很多时候某些不了解异常机制的人,由于对异常的性能开销的恐惧感,经常会做出这么脑残的决定
性能倒是高了,但是系统异常怎么办呢?一旦数据库出错就只等着系统崩溃了。某些有经验的说我会把下面的try{}catch{}起来,不过那不是脱了裤子放屁么,异常都抛出来了,开销已经产生了,结果换来的是牺牲了异常对象的丰富信息而换来了畸形的系统逻辑。性能也没得到提高
*/
//典型错误4
public bool InsertUser(User user,ref int errcode)
{
     if(user==null)
    {
        errcode=110;//参数为空错误的代码            return false;
    }
    //调用Orm
}    

三、异常的性能测试

结论:

1、new Exception() 异常对象和创建普通对象的性能损耗没太大差别

2、throw 抛出异常时会造成系统性能损耗,主要在于“填充运行的堆栈信息”、“记录异常快照”等

3、try{}catch{}不会造成明显的系统开销,加不加性能区别不大

4、对外提供的方法尽可能抛出异常,避免程序崩溃,使用时请继承ApplicationException基类

5、业务逻辑上的数据尽量用if{}else{}过滤掉,不要靠throw new Exception()来处理

6、异常在程序中无法避免,合理使用避免程序崩溃才是唯一正确的道路

(以上结论仅代表个人观点)

    public class TyhTest
    {
        private string msg;
        public TyhTest(string msg)
        {
            this.msg = msg;
        }
    }

    public class TyhException : ApplicationException
    {
        //这种写法是继承基类构造方法
        public TyhException(string msg): base(msg)
        {

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int max = 100;
            int j = 1;
            string str = "a";
            //==========
            Stopwatch time1 = new Stopwatch();
            time1.Start();
            for (int i = 0; i < max; i++)
            {
                try
                {
                    if (j > 0 && !string.IsNullOrEmpty(str))
                        throw new Exception("Exception异常");
                }
                catch (Exception e)
                {

                }
            }
            time1.Stop();
            Console.WriteLine("抛出Exception异常耗时:" + time1.ElapsedMilliseconds);
            //==========
            Stopwatch time2 = new Stopwatch();
            time2.Start();
            for (int i = 0; i < max; i++)
            {
                try
                {
                    if (j > 0 && !string.IsNullOrEmpty(str))
                        throw new ApplicationException("Exception异常");
                }
                catch (ApplicationException e)
                {

                }
            }
            time2.Stop();
            Console.WriteLine("抛出ApplicationException异常耗时:" + time2.ElapsedMilliseconds);
            //==========
            Stopwatch time3 = new Stopwatch();
            time3.Start();
            for (int i = 0; i < max; i++)
            {
                try
                {
                    if (j > 0 && !string.IsNullOrEmpty(str))
                        throw new TyhException("Exception异常");
                }
                catch (Exception e)
                {

                }
            }
            time3.Stop();
            Console.WriteLine("抛出自定义TyhException异常耗时:" + time3.ElapsedMilliseconds);
            //==========
            Stopwatch time4 = new Stopwatch();
            time4.Start();
            for (int i = 0; i < max; i++)
            {
                try
                {
                    if (j > 0 && !string.IsNullOrEmpty(str))
                    {

                    }
                    else
                    {

                    }
                }
                catch (Exception e)
                {

                }
            }
            time4.Stop();
            Console.WriteLine("不抛异常用IF判断耗时:" + time4.ElapsedMilliseconds);
            //==========
            Stopwatch time5 = new Stopwatch();
            time5.Start();
            for (int i = 0; i < max; i++)
            {
                try
                {
                    var test = new TyhTest("创建对象");
                }
                catch (Exception e)
                {

                }
            }
            time5.Stop();
            Console.WriteLine("创建普通对象TyhTest耗时:" + time5.ElapsedMilliseconds);
            //==========
            Stopwatch time6 = new Stopwatch();
            time6.Start();
            for (int i = 0; i < max; i++)
            {
                try
                {
                    var test = new Exception("创建异常对象");
                }
                catch (Exception e)
                {

                }
            }
            time6.Stop();
            Console.WriteLine("创建异常对象Exception耗时:" + time6.ElapsedMilliseconds);

            Console.ReadKey();
        }
}

(Stopwatch 不需要 new 很多个,代码复制粘贴的,请忽略,忽略,哈哈~)

时间: 2024-10-03 10:30:08

正确使用Exception异常对象的相关文章

[python] 之 异常对象

一.异常对象 类异常支持异常的层次结构:超类变成分类名称,而子类变成这个分类中特定种类的异常.except字句列出一个通用的异常超类,就可捕捉整个分类中的各种异常:任何特定的子类都可匹配. 1 class General(Exception):pass 2 class Specific1(General):pass 3 class Specific2(General):pass 4 5 def raise0(): 6 x=General() 7 raise x 8 9 def raise1():

Java Exception异常介绍

 一:介绍java异常 异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwable类的众多子类描述各种不同的异常.因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件.当条件生成时,错误将引发异常. 在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出).Throwable 指定代码中可用异常传播机制通过 Java 应用程序

C++ 异常对象

1.catch子句参数为对象 先看一段代码: #include <iostream> #include <exception> using namespace std; class MyException :public exception{ public: MyException(){ cout<<"MyException()"<<endl; } ~MyException(){ cout<<"~MyExceptio

PHP中Exception异常

异常的基本使用 当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块.如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 "Uncaught Exception" (未捕获异常)的错误消息.让我们尝试抛出一个异常,同时不去捕获它: <?php //create function with an exception functio

ckecked Exception和Unchecked Exception异常

Throwable 是所有 Java 程序中错误处理的父类 Error JVM Exception 程序 Checked Exception:继承java.lang.Exception 代表程序不能控制的无效外界情况.除了Error以及RuntimeException(运行时异常)及其子类,如:ClassNotFoundException, NamingException, ServletException, SQLException, IOException等.JAVA 编译器强制要求try

Exception异常

System.err.println(“出现异常:类型转换错误”) void printStackTrace():输出异常的堆栈信息 String getMessage(): 返回异常的描述字符串 常见的异常类型:        Exception:                 异常结构的基类        ArithmeticException:          运行时异常,算术运算错误        ArrayIndexOutBoundException: 数组下标越界       

PLSQL_Oracle Exception异常分类、异常抛出、异常处理、异常传播(概念)

2014-06-03 BaoXinjian 一.摘要 在PLSQL程序开发过程中,很重要的部分就是对程序异常的监控和处理,包括如何触发异常,何时进行处理,如何进行处理,是否将程式中的所有异常集中在一起,通过公共异常处理的procedure或function,如果没有完善的程式处理机制,很难说该程式是一只健壮的程式,当程式遇到很多类型或者量很多资料时,系统若没有异常处理必然会导致程式的出错 当预判到了某些异常,需要对预判到的异常进行合适相应的处理,是否抛出异常还是忽略还是其他 当然程式没有预判到或

最常见到的runtime exception 异常

ArithmeticException, 算术异常ArrayStoreException, 将数组类型不兼容的值赋值给数组元素时抛出的异常BufferOverflowException, 缓冲区溢出异常BufferUnderflowException, 缓冲区下溢异常 CannotRedoException, 不能重复上一次操作异常 CannotUndoException, 不能撤销上一次操作异常ClassCastException, 类型强制转换异常ClassNotFoundException

Exception 异常 输出的各个方法的区别

try{ System.out.println(1/0); }catch(Exception e){ //System.out.println(e+""); //对象+字符串 = 对象.toString + 字符串 System.out.println(e); //1 System.out.println("<><><><><><><><><><><&