前言

在编程中异样报错是不可避免的。特地是在学习某个语言初期,看到异样报错就抓耳挠腮,经常开玩笑说编程1分钟,改bug1小时。明天就让咱们来看看什么是异样和怎么正当的解决异样吧!

异样与error介绍

上面还是先让咱们来看一下基本概念吧!

异样指程序运行过程中呈现的非正常景象,例如用户输出谬误、除数为零、须要解决的文件不存在、数组下标越界等。异样机制实质就是当程序呈现谬误,程序平安退出的机制。在Java的异样解决机制中,引进了很多用来形容和解决异样的类,称为异样类。异样类定义中蕴含了该类异样的信息和对异样进行解决的办法。

Java是采纳面向对象的形式来解决异样的。处理过程:

  1. 抛出异样:在执行一个办法时,如果产生异样,则这个办法生成代表该异样的一个对象,进行以后执行门路,并把异样对象提交给JRE。
  2. 捕捉异样:JRE失去该异样后,寻找相应的代码来解决该异样。JRE在办法的调用栈中查找,从生成异样的办法开始回溯,直到找到相应的异样解决代码为止。

让咱们来看看后面所讲到的异样类到底是个什么货色!

其实所有的异样对象都是派生于Throwable类的一个实例。如果内置的异样类不可能满足需要,还能够创立本人的异样类。所有异样的根类为java.lang.Throwable。看看它的家族长什么样。

Throwable类上面次要是两大门派。ErrorException

  • Error是程序无奈解决的谬误,示意运行应用程序中较重大问题,零碎JVM曾经处于不可复原的解体状态中。例如,说内存溢出和线程死锁等零碎问题。
  • Exception是程序自身可能解决的异样。

    Exception类是所有异样类的父类,其子类对应了各种各样可能呈现的异样事件。 通常Java的异样可分为:

    1. RuntimeException 运行时异样
    2. CheckedException 已查看异样

上面咱们来钻研钻研这两个异样。

RuntimeException和 CheckedException异同

首先咱们先来看看什么是运行时异样

这类异样通常是由编程谬误导致的,所以在编写程序时,并不要求必须应用异样解决机制来解决这类异样,而是常常须要通过减少“逻辑解决来防止这些异样”。

比方以下常见的几种异样:

ArithmeticException异样

 int b=0; System.out.println(1/b); //解决:   if(b!=0){      System.out.println(1/b);   }

NumberFormatException异样

String str = "1234abcf";System.out.println(Integer.parseInt(str));//解决: Pattern p = Pattern.compile("^\\d+$");Matcher m = p.matcher(str);if (m.matches()) { // 如果str匹配代表数字的正则表达式,才会转换    System.out.println(Integer.parseInt(str));}

ClassCastException异样

Animal a=new Dog();Cat c=(Cat)a;//解决:    if (a instanceof Cat) {    Cat c = (Cat) a;}

这里再补充两点,不便大家更好的了解java异样的机制和处理过程。

  1. 在办法抛出异样之后,运行时零碎将转为寻找适合的异样处理器(exception handler)。潜在的异样处理器是异样产生时顺次存留在调用栈中的办法的汇合。当异样处理器所能解决的异样类型与办法抛出的异样类型相符时,即为适合的异样处理器。
  2. 运行时零碎从产生异样的办法开始,顺次回查调用栈中的办法,直至找到含有适合异样处理器的办法并执行。当运行时零碎遍历调用栈而未找到适合的异样处理器,则运行时零碎终止。同时,意味着Java程序的终止。

下面咱们讲述了什么是运行时异样以及一些解决形式,上面就再来看看什么是已查看异样吧!

所有不是RuntimeException的异样,统称为Checked Exception,又被称为“已查看异样”,如IOException、SQLException等以及用户自定义的Exception异样。 这类异样在编译时就必须做出解决, 否则无奈通过编译。

通常异样的解决形式有两种:

  1. 应用“try/catch”捕捉异样
  2. 应用“throws”申明异样。

上面就来具体的聊聊吧!

异样的解决

下面曾经提了,异样解决通常有2种形式。先看看捕捉异样吧。

捕捉异样是通过3个关键词来实现的:try-catch-finally。用try来执行一段程序,如果出现异常,零碎抛出一个异样,能够通过它的类型来捕获(catch)并解决它,最初一步是通过finally语句为异样解决提供一个对立的进口,finally所指定的代码都要被执行。

这个捕捉异样其实也是咱们在面试的时候会常常碰到的问题。上面咱们别离再来对各个局部做一个简略的提醒吧!

  • try

一个try语句必须带有至多一个catch语句块或一个finally语句块 。当异样解决的代码执行完结当前,不会再回到try语句去执行尚未执行的代码。

  • catch

每个try语句块能够随同一个或多个catch语句,用于解决可能产生的不同类型的异样对象。在此介绍一些罕用的办法,这些办法均继承自Throwable类 。

  1. toString ()办法,显示异样的类名和产生异样的起因。
  2. getMessage()办法,只显示产生异样的起因,但不显示类名。
  3. printStackTrace()办法,用来跟踪异样事件产生时堆栈的内容。

这里有一个须要特地留神的中央,那就是catch捕捉异样时的捕捉程序:

如果异样类之间有继承关系,在程序安顿上就需注意。越是顶层的类,越放在上面,再不然就间接把多余的catch省略掉。 也就是说先捕捉子类异样再捕捉父类异样。

  • finally

finally语句块中始终都要执行,除了遇到了System.exit(0)完结程序运行。针对这个个性,所以咱们通常在finally中关闭程序块已关上的资源,比方:敞开文件流、开释数据库连贯等。

即便try和catch块中存在return语句,finally语句也会执行。是在执行完finally语句后再通过return退出。

在这里就有一道十分经典的一个面试题。

public class Test {    public static void main(String[]args) {       System.out.println(new Test().test());;    }    static int test(){       int x = 1;       try{          retun x;       }finally{          System.out.print("jdbk"+ ++x);       }    }}// 问输入后果?

先解释哈这里存在的玄妙吧!

看了下面的讲述,咱们都晓得了当try和catch中有return时,finally依然会执行,所以失常逻辑来说此题的答案应该是“jdbk2 2”,但这里存在一个陷阱,那就是:

finally是在return前面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保 存起来,不论finally中的代码怎么样,返回的值都不会扭转,任然是之前保留的值),所以函数返回值是 在finally执行前确定的。因而正确答案应该是:“jdbk2 1”。

还有一点须要留神的就是:finally中最好不要蕴含return,否则程序会提前退出,返回值不是try或catch中保留的返回值。

接下来再来讲讲申明异样吧,它相对来说就比较简单了。

在一些状况下,以后办法并不需要解决产生的异样,而是向上传递给调用它的办法解决。如果一个办法抛出多个已查看异样,就必须在办法的首部列出所有的异样,之间以逗号隔开。

public static void readFile(String fileName) throws FileNotFoundException,IOException {}

须要留神的中央就是:

  1. 在办法重写中申明异样时:子类重写父类办法时,如果父类办法有申明异样,那么子类申明的异样范畴不能超过父类申明的范畴。
  2. 申明异样咱们个别在server层中。在controller层或则数据拜访层个别是捕捉异样。

自定义异样

咱们为什么要自定义异样?还不是因为在程序中,可能会遇到JDK提供的任何规范异样类都无奈充沛形容分明咱们想要表白的问题。此时咱们就能够创立本人的异样类,即自定义异样类。

那咱们怎么自定义异样类呢?置信你看了下面的异样类的家族图应该就猜到了。不错,自定义异样类只需从Exception类或者它的子类派生一个子类即可。如果你继承Exception类,则为受查看异样,必须对其进行解决;如果不想解决,能够让自定义异样类继承运行时异样RuntimeException类。通常咱们自定义异样类应该蕴含2个结构器:一个是默认的结构器,另一个是带有详细信息的结构器。这里举一个例子。

/**IllegalAgeException:非法年龄异样,继承Exception类*/class IllegalAgeException extends Exception {    //默认结构器    public IllegalAgeException() {         }    //带有详细信息的结构器,信息存储在message中    public IllegalAgeException(String message) {        super(message);    }}   public void setAge(int age) throws IllegalAgeException {        if (age < 0) {            throw new IllegalAgeException("人的年龄不应该为正数");        }        this.age = age;    }

最初给大家讲述一点应用异样机制的倡议:

1.要防止应用异样解决代替错误处理,这样会升高程序的清晰性,并且效率低下。

2.解决异样不能够代替简略测试---只在异常情况下应用异样机制。

3.不要进行小粒度的异样解决---应该将整个工作包装在一个try语句块中。

4.异样往往在高层解决。


最初,最近很多小伙伴找我要Linux学习路线图,于是我依据本人的教训,利用业余时间熬夜肝了一个月,整顿了一份电子书。无论你是面试还是自我晋升,置信都会对你有帮忙!

收费送给大家,只求大家金指给我点个赞!

电子书 | Linux开发学习路线图

也心愿有小伙伴能退出我,把这份电子书做得更完满!

有播种?心愿老铁们来个三连击,给更多的人看到这篇文章

举荐浏览:

  • 干货 | 程序员进阶架构师必备资源免费送
  • 神器 | 反对搜寻的资源网站