澳门在线威尼斯官方 > 澳门在线威尼斯官方 > 你不知道的异常处理

原标题:你不知道的异常处理

浏览次数:99 时间:2019-09-15

介绍

不管是新手还是工作几年的老油条,对try{}catch{}来说是不陌生的。他可以来帮助我们获取异常信息,在try中的代码出现错误,火灾catch代码块中被捕获到。官方也给了详细的解释:。

抛出异常时,公共语言运行库(CLR)会查找catch处理此异常的语句。如果当前正在执行的方法不包含这样的catch块,则CLR会查看调用当前方法的方法,依此类推调用堆栈。如果未catch找到任何块,则CLR向用户显示未处理的异常消息并停止执行该程序。

以上的这些基础我们可能都了解。但是你真的了解他的运行步骤吗?我就是带着这个疑问进行了一下的几个测试。

问:关于 java 中的异常处理你有啥心得或者经验?

简单示例:

既然有了疑问就带着疑问想办法验证吧,下面我们通过多个例子来一步一步的分析得到我们想要的结果。

答:这其实是一个经验题,答案不局限的,可以自由发挥,下面给出几个示例点。

简单的try catch

首先是一个try中没有异常的示例:

 static void Main(string[] args)
        {
            string result =GetStr();
            Console.WriteLine(result);
            Console.ReadLine();
        }
        public static string GetStr()
        {
            try
            {
                Console.WriteLine("走到:try");
                return "这里是try返回值";
            }
            catch (Exception e)
            {
                Console.WriteLine("走到:catch");
                return "这里是catch返回值";
            }
            finally
            {
                Console.WriteLine("走到:finally");
            }
            return "这里是方法底部返回值";
        }

运行结果:

图片 1

执行分析:

这是最简单最常见的示例,没有发生异常,然后没有走catch,执行顺序是try=>finally=>return;

所有我们得到一个还不确定的结果在GetStr方法中不会执行方法自己的return;

但是finally方法块都会执行;

方法返回值尽量不要使用 null(特殊场景除外),这样可以避免很多 NullPointerException 异常。

来个异常的:

下面我们让try方法块出错就好了,然后我们修改一下代码如下:

 public static string GetStr()
        {
            try
            {
                int value = 0;
                Console.WriteLine("走到:try");
                var i = 1 / value;//这里会出错 0不能被整除
                return "这里是try返回值";
            }
            catch (Exception e)
            {
                Console.WriteLine("走到:catch");
                return "这里是catch返回值";
            }
            finally
            {
                Console.WriteLine("走到:finally");
            }
            return "这里是方法底部返回值";
        }

运行结果:

图片 2

执行分析:

这里在try发生了异常,然后没有正常返回,进入到了catch方法块:try=>catch=>finally=>return;

这里我们可以确定:

  • 不管try有没有出错finally方法块都会被执行。【快记笔记,知识点。】
  • 就算try和catch方法都有return,finally都会执行;
  • 只要try或者catch return返回,try catch 之外的return都无效;

说到这里有些不懂得人可能会有疑问?那在finally写个return是什么结果哪?很不幸的告诉你,不能这么写,写了会怎么样,哼会提示:控制不能离开finally子句主体;

catch 住了如果真的没必要处理则至少加行打印,这样可在将来方便排查问题。

验证return的值

上面我们知道了怎样都会执行finally,但是执行了finally对我们的正返回值有没有印象哪,例如我在try里面对一个变量赋值为a字符串,进行了返回,但是在finally里面修改成了b字符串。会不会被修改哪?

我们还是老代码,然后修改成我们想的样子:

public static string GetStr()
        {
            string str = "";
            try
            {
                str = "修改成了a";
                Console.WriteLine("走到:try");
                // return "这里是try返回值";
                return str;
            }
            catch (Exception e)
            {
                Console.WriteLine("走到:catch");
                return "这里是catch返回值";
            }
            finally
            {
                str = "修改成了b";
                Console.WriteLine("走到:finally");
            }
            return "这里是方法底部返回值";
        }

运行结果:

图片 3

执行分析:

没有异常还是老样子:执行顺序是try=>finally=>return;

但是我们在finally修改了str字符串,但是通过输出结果我们得到的还是a字符串,

所有我们得到结论:虽然finally方法会被执行但是,返回结果不会被改变,也就是如果finally是在return之后执行的那么他会把返回结果先保存起来,然后不管finally代码执行了什么,都不会影响到返回结果,等finally执行完成在返回结果。

接口方法抛出的异常尽量保证是运行时异常类型,除非迫不得已才抛出检查类型异常。

 多个重复try

那么我们可以写多个try{}try{}这样的语句吗?不行,会直接报错,其实这样写没有任何意义。

避免在 finally 中使用 return 语句或者抛出异常,如果调用的其他代码可能抛出异常则应该捕获异常并进行处理,因为 finally 中 return 不仅会覆盖 try 和 catch 内的返回值且还会掩盖 try 和 catch 内的异常,就像异常没有发生一样(特别注意,当 try-finally 中没有 return 时该方法运行会继续抛出异常)。

多个重复catch

那么重复多个catch哪?这个是可以的例如下面我这样:

  try
            {
                str = "修改成了a";
                Console.WriteLine("走到:try");
                // return "这里是try返回值";
                return str;
            }
            catch(InvalidCastException e) {
            }
            catch (Exception e)
            {
                Console.WriteLine("走到:catch");
                return "这里是catch返回值";
            }

这个是被允许的,因为这是有意义的写法。

尽量不要在 catch 块中压制异常(即什么也不处理直接 return),因为这样以后无论抛出什么异常都会被忽略,以至没有留下任何问题线索,如果在这一层不知道如何处理异常最好将异常重新抛出由上层决定如何处理异常。

开始升级

为什么要一定写try-catch-finally 我只写其中一部分不可以吗?

方法定义中 throws 后面尽量定义具体的异常列表,不要直接 throws Exception。

 try-catch

那么我们这次不写finally试一试吧。try方法块没有异常已经不用测了,因为上面我们已经确认过了。会返回try的内容。那么就try异常吧。

 public static string GetStr()
        {
            try
            {
                Console.WriteLine("走到:try");
                int value = 0;
                int s = 1 / value;              
                return "这里是try返回值";
            }
            catch (Exception e)
            {
                Console.WriteLine("走到:catch");
                return "这里是catch返回值";
            }
            return "这里是方法底部返回值";
        }

运行结果:

图片 4

执行分析:

通过可以正常运行我们知道这样写一点问题都没有,所以结果就是

  • finally也不是必须的。
  • 如果catch没有return 就会返回底部return方法。这是我们的常识。

这样做有什么作用或者意义哪,通常我们可以上面说的定义多个catch来检测异常,还有一个用途就是忽略异常,就是这种异常你系统可以被运行,就可以catch内不写return正常跳过异常执行下面的方法体。但是不是很被建议,

捕获异常时尽量捕获具体的异常类型而不要直接捕获其父类,这样容易造成混乱。

try-finally

那么try-finally哪,这样写也是被允许的。

这样单独写第一就是在finally语句块内做try的资源释放。正常情况下try没有异常,在finally中处理try语句块的资源释放。

第二就是try发生了异常,其实finally起到的作用还是一样的。但是这里区别在于如果异常未经处理,可能就导致程序退出了。所有执不执行已经无所谓了。我们来个异常示例:

图片 5图片 6

static void Main(string[] args)
        {
            string result = "";
            try
            {
                result = GetStr();
            }
            catch (Exception e)
            {
                Console.WriteLine("主方法catch:");
            }
            Console.WriteLine(result);
            Console.ReadLine();
        }
        public static string GetStr()
        {
            try
            {
                Console.WriteLine("走到:try");
                int value = 0;
                int s = 1 / value;               
                return "这里是try返回值";
            }

            finally
            {
                Console.WriteLine("走到:finally");
            }

            return "这里是方法底部返回值";
        }

View Code

运行结果:

图片 7

执行分析:

try发生了异常,但是因为finally始终都会执行所有也会执行,然后异常被调用方法内的catch捕获执行顺序:try=>finally=>catch(主方法)

所有我们得到结果:

  • try-finally可以运行
  • try如果没有catch但是发生异常会向上找catch方法块来捕获。知道没有系统崩溃。

以上的例子都是非控制(系统出现异常就自动抛出了)的抛出异常,那么我们可以控制异常的抛出点吗?当然可以。

避免在 finally 块中抛出异常,不然第一个异常的调用栈会丢失。

本文由澳门在线威尼斯官方发布于澳门在线威尼斯官方,转载请注明出处:你不知道的异常处理

关键词:

上一篇:在线运行

下一篇:没有了