【Java入门提高篇】Day16 Java异常处理(上)

当当当当当当,各位看官,好久不见甚是想念

 

  今天我们来聊聊Java里的一个小妖精,那就是异常

 

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

  异常嘛,顾名思义就是不正常,(逃),是Java程序运行时,发生的预料之外的事情,它阻止了程序按照程序员的预期正常执行。

 

  异常处理,应该说异常处理机制,就是专门用来制服这个小妖精的法宝。Java中的异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。

 

  简而言之,Java异常处理就是能让我们主动迎击可能到来的异常,并将它们以圆润的方式处理掉。

 

  还是先来看个小栗子,看看java里的异常长什么样。

 

 

public class Test {

    public static void main(String args[]){

        int i = 0 / 0;

        System.out.println("i = " + i);

    }

}

 

  

 

  别慌别慌,不要看到红色提示就内心崩溃只想关掉IDE,来,抓紧我的手,带你看清“异常”这个磨人的小妖精的真面目(滑稽)。

 

  代码里将0作为了分母,因此程序会发生算术异常,抛出一个异常后,如果没有任何处理,默认会终止程序,所以后面的打印内容并没有输出。在异常内容里,有说明异常类型为:java.lang.ArithmeticException,也就是算术异常,后面跟着的是异常原因: / by zero,也就是说异常出现的原因是将0作为了分母,而且后面还有堆栈信息,指出了异常抛出的位置是在com.frank.chapter16.main.Test.main这个包下,Test类的第11行(这个行数如果跟你想的不一样,不要在意,因为我的代码开始之前还有一些不可描述的说明信息),因为只有一次方法调用,所以没有很长的堆栈信息,看起来也很简洁明了。

 

  所以你看,其实异常也没那么可怕吧,不仅给了异常原因,还告诉了你这个bug是出在第几行,所以好好利用它,可以帮助你写出更难以发现的bug,呸,说错了,可以帮助你更容易找到bug(手动滑稽)。

 

  如果不希望抛出异常后程序就结束,而是希望它继续运行呢?那么就捕获它。

 

如何使用异常处理

  我们来把上面那个栗子改改:

 

 

public class Test {

    public static void main(String args[]){

        try{

            int i = 0 / 0;

        }catch (Exception e){

            System.out.println("好像发生异常了,但是我不管,我还要继续运行");

        }

        System.out.println("运行完毕!");

    }

}

 

  输出如下:

 

好像发生异常了,但是我不管,我还要继续运行

运行完毕!

  好的,很强势,现在即使抛出了异常,程序也继续运行了。异常就像是一头野兽,但你一旦捕获它,驯服它,就可以为你所用,为所欲为了。

 

  try...catch...是常用的异常处理搭配,如果在try语句块中发生了异常,如果刚好这个异常被捕获到了,那么会直接跳到catch语句块中,执行catch语句中的代码,像上面的栗子里,因为对Exception类进行了捕获处理,所以当它的子类异常java.lang.ArithmeticException被抛出来的时候,也能捕获它。关于Exception类的结构层次关系,后面再做详细介绍。

 

  还有另外一种搭配方式,那就是try...catch...finally,finally语句块比catch要强势的多,前面说了catch语句块必须要捕获到了特定的Exception才会执行里面的代码,如果catch的是ArithmeticException但是抛出的却是空指针异常,那就不会被捕获了,异常也就逃之夭夭了。这个时候,finally的优势就展示出来了,不管抛出什么样的异常,也不管是否抛出了异常,finally中的代码都会被执行。所以一般的用法是在finally语句块里释放掉那些需要被释放的资源,如socket连接,关闭io流,关闭数据库连接等等。也就是说一般在finally中收拾try中抛出的烂摊子,心疼一秒finally,果然能者多劳啊。

 

  当然,try...finally这样的搭配也是ok的,需要注意的是,当try语句中发生了异常之后,在发生异常处之后的代码将不会再执行,而是跳到相应的catchu或者finally中去。

 

 

public class Test {

    public static void main(String args[]){

        try{

            int i = 0 / 0;

        }catch (NullPointerException e) {

            System.out.println("这里捕获空指针异常");

        }catch (ArithmeticException e){

            System.out.println("这里捕获算术异常");

        }finally {

            System.out.println("这里是finally");

        }

        System.out.println("运行完毕!");

    }

}

 

  输出如下:

 

这里捕获算术异常

这里是finally

运行完毕!

  在上面的代码中,catch语句块是可以同时使用多个的,第一个catch语句块捕获的是空指针异常,但由于抛出的是算术异常,所以没有捕获住,但被第二个catch捕获到了,所以第二个catch语句块中的代码执行了。异常匹配是按照从上到下的顺序进行匹配的,最后才执行finally中的代码块。关于try...catch...finally,还有一个很有趣的return问题,如果三个语句块里都有return,最终返回结果会是怎样呢?这里做了详细的说明,http://www.cnblogs.com/mfrank/p/7895660.html 有兴趣的话可以看一看。

 

  绝大多数情况下,finally中的代码都是会被执行的,只有一种情况下,finally中的代码不会被执行,那就是在try语句块中结束掉了虚拟机(如:使用 System.exit(0); )。

 

  关于异常,还有一个关键字需要介绍,那就是throw,使用throw可以主动抛出一个异常。看到这你也许会一脸懵逼,主动抛出???嫌异常不够多,凑热闹不嫌事大??别急别急,中间一定有什么误会,把刀放下,有话好好说。

 

  throw关键字确实是用来抛出异常的,你可以这样使用:

 

 

public class Test {

    public static void main(String args[]){

        try{

            throw new NullPointerException("听说你很闲,给你抛个异常。");

        }catch (NullPointerException e) {

            System.out.println("这里捕获空指针异常,提示内容:" + e.getMessage());

            e.printStackTrace();

        }

    }

}

 

  输出如下:

 

这里捕获空指针异常,提示内容:听说你很闲,给你抛个异常。

java.lang.NullPointerException: 听说你很闲,给你抛个异常。

    at com.frank.chapter16.main.Test.main(Test.java:11)

  用throw关键字可以抛出任意类型的异常,当然,你想的话,还有抛Error,至于什么是Error,已经跟Exception的关系,将在下一篇里进行讲解。暂时不用深究。

 

  在throw异常的时候,可以加上抛出异常的原因,这样可以更方便定位问题所在,当然,一般来说不会像栗子中这样使用的,这里只是为了简单起见。

 

  到此为止,异常的上半篇已经讲解完毕,在这一篇里,说明了什么是异常,什么是异常处理,以及如何使用异常处理机制。相信大家对这个小妖精有了初步的认识,下一篇中,将会讲解Exception家族都有哪些成员,如何使用自定义异常,已经异常处理的实际使用中的正确姿势。欢迎大家继续关注,之后计划每周两篇以上的更新,如果有讲解遗漏或者不好的地方,欢迎大家及时指出,共同进步!

---------------------

作者:弗兰克的猫__

来源:CSDN

原文:https://blog.csdn.net/MFrank2018/article/details/80527032

版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值