异常处理机制

1. 概念

  1. - **异常**:指程序在运行当中出现的非正常的情况,最终会导致JVM的非正常运行,在JAVA等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常并抛出了一个异常对象。JAVA处理异常的方式是中断处理。
  2. - **分类**:根类是Throwable,其下有两个子类:
  3. - **Error**:工程师不能处理,只能避免
  4. - **Exception**:由于使用不当导致,可以避免(RunTimeException:运行期异常)
  5. - **处理:**
  6. - **抛出:抛出异常并终止程序<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580796156036-2fd41982-5d2a-4b6b-a624-47aae1c80801.png#align=left&display=inline&height=155&name=image.png&originHeight=155&originWidth=656&size=14362&status=done&style=none&width=656)**
  7. - **捕捉:可以继续运行后边的程序<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580796268024-0a8a0f7a-17c4-4189-9e11-39ba8d50e075.png#align=left&display=inline&height=254&name=image.png&originHeight=254&originWidth=649&size=18219&status=done&style=none&width=649)**
  8. - **错误:只能修改源代码(分配空间不足:硬伤)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580796369144-a6a618af-3e3c-4b8b-b2f5-d55b63cebd59.png#align=left&display=inline&height=81&name=image.png&originHeight=81&originWidth=383&size=4182&status=done&style=none&width=383)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580796376773-c7039b53-e2f7-4914-9878-59018a60b6f5.png#align=left&display=inline&height=58&name=image.png&originHeight=58&originWidth=647&size=5388&status=done&style=none&width=647)**

Checked+RunTime异常

  1. Checked异常:编译期异常,这个就像你的要求超过了计算机的物理限度,是无法实现的,必须处理
  2. Run Time异常:运行期异常,这个异常可以不处理,留给虚拟机处理,可以意识到犯错的位置
    • 详细内容在这篇笔记中有说明

throw抛出异常

1. 使用简析

  1. - **作用**:使用throw关键字在指定的方法中抛出指定的异常
  2. - **使用:**
  3. - 在方法名之后声明异常,然后再方法中才能抛出异常;
  4. - throw new xxxException"异常产生的原因");
  5. - <br />
  6. - **注意:**
  7. - throw关键字必须写在方法的内部
  8. - throw关键字后边new的对象必须是Exception或者Exception的子类
  9. - throw关键字抛出指定的异常对象,我们就必须处理这个异常对象<br />throw关键字后边创建的是RuntimeException或者RuntimeException的子类,我们可以不管<br />throw关键字后边创建的是编译器异常(写代码时报错),那么就要用throws或者try...catch
  10. - 方法内部如果抛出了多个异常对象,那么throws后边必须也声明多个异常,如果抛出的多个异常对象有父子关系,那么直接声明父类异常即可

2. 使用场景

  1. - 方法传递参数时:首先要对传递过来的参数进行合法性检验,如果有问题就抛出异常<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580798629929-e01e05d3-a591-4d0d-9233-a88ab96c674c.png#align=left&display=inline&height=282&name=image.png&originHeight=282&originWidth=558&size=16139&status=done&style=none&width=558)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580798645512-a17efc20-5d27-4761-ab3b-04d5d50847ed.png#align=left&display=inline&height=82&name=image.png&originHeight=82&originWidth=696&size=8669&status=done&style=none&width=696)
  2. - 数组越界<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580802074523-5bddbdf0-2637-4227-af5d-139d75a8bf19.png#align=left&display=inline&height=405&name=image.png&originHeight=405&originWidth=724&size=28493&status=done&style=none&width=724)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580802089299-d2c1c66e-fc34-4811-998b-2402e76b5761.png#align=left&display=inline&height=77&name=image.png&originHeight=77&originWidth=876&size=10641&status=done&style=none&width=876)
  3. - Object类空指针(第二个参数是输出的信息,第一行的方法不会输出自定义信息)<br />**![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580802674001-d5fce65b-86fb-40df-996c-812ae62fcf22.png#align=left&display=inline&height=208&name=image.png&originHeight=208&originWidth=547&size=13847&status=done&style=none&width=547)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580802705307-9c885594-5025-4059-b06f-8bab4b6ed076.png#align=left&display=inline&height=102&name=image.png&originHeight=102&originWidth=695&size=11454&status=done&style=none&width=695)**
  4. - **文件名检测(这个是编译异常,需要多次抛出声明,提前解决,或者try...catch:此时不用在main方法处声明)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580804632012-c93ea9da-5c32-459a-8c35-71507f330b6e.png#align=left&display=inline&height=234&name=image.png&originHeight=234&originWidth=687&size=18087&status=done&style=none&width=687)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580804672840-a77daaf1-88af-4a61-bd17-6989fc52b594.png#align=left&display=inline&height=100&name=image.png&originHeight=100&originWidth=671&size=11333&status=done&style=none&width=671)**
  5. - **后缀名检测(使用的是文件名异常抛出类的父类,两个一起使用,只需声明父类即可)**![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580805315041-4e2aa1f4-5525-4639-817a-8bbc7f74e038.png#align=left&display=inline&height=366&name=image.png&originHeight=366&originWidth=597&size=23784&status=done&style=none&width=597)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580805368053-5b0c057b-8dab-4a17-af39-d9f41ea7c0be.png#align=left&display=inline&height=86&name=image.png&originHeight=86&originWidth=581&size=7889&status=done&style=none&width=581)

3. 常用异常类

  1. - **NullPointerException类:空指针异常,是运行期异常。**
  2. - **ArrayIndexOutOfBoundsException类:数组越界异常,运行期异常**
  3. - **Objects.requireNonNull()方法:自动抛出异常**
  4. - **FileNotFoundException类:IO流异常(文件名),是****编译期异常****,必须处理**
  5. - **IOException类:真正的IO流异常,是前者的父类(filename.endWith()方法可以用来检测后缀名,盲猜是检测字符串后侧小字符串的正确性,确实是)**

4. Trowable中的三个异常处理类

  1. - 输出内容的详细程度不同(输出的内容是类中定义的输出内容)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580810851775-e7c615ea-0932-4fd6-b808-56ef69c69605.png#align=left&display=inline&height=487&name=image.png&originHeight=487&originWidth=604&size=34405&status=done&style=none&width=604)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580810881035-92998b7c-0612-494d-9086-3a28dbfa0825.png#align=left&display=inline&height=159&name=image.png&originHeight=159&originWidth=396&size=13132&status=done&style=none&width=396)

Try…Catch自定异常

1. 概念

  1. - 简介:异常处理的第二种方式,自己处理异常
  2. - 格式:
  3. - try{<br /> 可能产生异常的代码<br />}catch(定义一个异常的变量,用来接受try中抛出的异常对象){<br /> 异常的处理逻辑,捕捉异常对象之后,怎么处理异常对象<br /> 一般在工作中,会把异常的信息记录到一个日志中<br />}<br />...<br />catch(异常类名 变量名){<br /> catch可以多次使用<br />}

2. 使用方法

  1. - 可以直接忽略main方法后的抛出声明,直接在main方法中捕捉并处理异常(这样的异常不是红色)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580807416078-9994de49-84c6-41c4-8251-5e23f4428a97.png#align=left&display=inline&height=387&name=image.png&originHeight=387&originWidth=594&size=26349&status=done&style=none&width=594)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580809799932-533391b8-48b8-4972-8de1-8e88f05bf01f.png#align=left&display=inline&height=31&name=image.png&originHeight=31&originWidth=259&size=2341&status=done&style=none&width=259)

3. 特殊情况

  1. - 无论如何必须执行的代码的位置
  2. - 使用finallycatch后方声明即可(不能单独使用,必须跟随try,一般用于读取文件后的资源释放)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580817010111-329d033c-b361-4668-aa5e-ff750993c4a6.png#align=left&display=inline&height=435&name=image.png&originHeight=435&originWidth=586&size=29093&status=done&style=none&width=586)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580817021424-1058e609-567c-4448-ab8f-87654ef38ce4.png#align=left&display=inline&height=52&name=image.png&originHeight=52&originWidth=150&size=2261&status=done&style=none&width=150)
  3. - finally中的return语句:无论如何都是返回finally中的return内容,就算是try中也有return方法<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580821489351-a8224279-2e18-4a47-b22b-eef3c76c0bc9.png#align=left&display=inline&height=381&name=image.png&originHeight=381&originWidth=423&size=15601&status=done&style=none&width=423)![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580821496847-e4790f2d-9722-4e4b-afd3-cb77ed31e93f.png#align=left&display=inline&height=28&name=image.png&originHeight=28&originWidth=75&size=405&status=done&style=none&width=75)

4. 多异常处理

  1. - 分开单个处理(list.of是在JAVA8之后出现的)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580819586885-f6ad95a8-98f1-4507-ad89-637e10765b41.png#align=left&display=inline&height=431&name=image.png&originHeight=431&originWidth=454&size=23222&status=done&style=none&width=454)![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580819638510-3dd489fb-d6d8-494b-8cef-c73e579cf072.png#align=left&display=inline&height=81&name=image.png&originHeight=81&originWidth=109&size=1516&status=done&style=none&width=109)
  2. - 多个异常一次捕获,多次处理(需要注释掉第一个异常才会显示第二个异常,也就是一次只能显示一个异常,不是太好用)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580819880919-ecf883b4-6abf-4ecb-be01-18b94ca76143.png#align=left&display=inline&height=381&name=image.png&originHeight=381&originWidth=436&size=22206&status=done&style=none&width=436)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580819939400-06159f2b-93b9-4e14-a513-0564b18a0754.png#align=left&display=inline&height=59&name=image.png&originHeight=59&originWidth=123&size=1392&status=done&style=none&width=123)![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580819973107-5bf649cc-bbfe-4d73-9a06-c30d8af520da.png#align=left&display=inline&height=54&name=image.png&originHeight=54&originWidth=171&size=1962&status=done&style=none&width=171)<br />注意事项:如果两个catch到的变量类型是子父类关系,那么子类必须在上(否则如下报错)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580820157609-4fe84223-53f2-4bef-b954-b09042962d62.png#align=left&display=inline&height=135&name=image.png&originHeight=135&originWidth=430&size=9242&status=done&style=none&width=430)
  3. - 多个异常一次捕获一次处理(其实就是上述的后一个catch删去,父类可以接受所有子类)(这样两个异常都可以正常处理)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580820479883-934757a4-79f4-4840-9631-3dec585857e1.png#align=left&display=inline&height=277&name=image.png&originHeight=277&originWidth=431&size=14698&status=done&style=none&width=431)
  4. - 万能异常处理:将IndexOutOfBoundsException改成Exception即可捕获所有的异常<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580820574402-965c97f4-108d-4a8d-b22d-c36fbfdc6980.png#align=left&display=inline&height=284&name=image.png&originHeight=284&originWidth=425&size=14178&status=done&style=none&width=425)![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580820582990-797949bc-c848-4896-a012-060d17b08c03.png#align=left&display=inline&height=55&name=image.png&originHeight=55&originWidth=167&size=1960&status=done&style=none&width=167)

子父类异常

1. 概念

  1. - 如果父类抛出了多个异常,子类重写父类方法的时候,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常
  2. - 父类方法没有抛出异常,子类重写父类该方法的时候也不可抛出异常,此时子类产生该异常,只能捕获处理,不能声明抛出

2. 注意

  1. - 父类异常什么样子,子类异常也就什么样子

3. 使用

  1. - 几种异常继承的演示(所有的子父类异常类型)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580822582234-abcaabe3-dece-4db7-a8ac-9fc6fa634094.png#align=left&display=inline&height=577&name=image.png&originHeight=577&originWidth=697&size=44843&status=done&style=none&width=697)

自定义异常类

1. 概念

  1. - JAVA提供的异常类不够用,需要自己定义一些异常类

2. 格式

  1. - public class xxxException extends Exception | RuntimeException{<br /> 添加一个空参数的构造方法<br /> 添加一个带异常信息的构造方法<br />}
  2. - Exception类<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580824938634-e37c65d4-1295-4766-971a-31dbbcab6f0b.png#align=left&display=inline&height=257&name=image.png&originHeight=257&originWidth=652&size=21201&status=done&style=none&width=652)
  3. - RuntimeException类(其实就换了一个单词)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580824977374-8213108e-1a54-4c74-9db5-75f884271eee.png#align=left&display=inline&height=252&name=image.png&originHeight=252&originWidth=651&size=21023&status=done&style=none&width=651)

3. 注意

  1. - 自定义异常类一般都是以Exception结尾,说明该类是一个异常类
  2. - 自定义异常类,必须得继承Exception或者RunTimeException
  3. - 继承Exception:是一个编译期异常,如果抛出了,必须处理(throws或者try...catch
  4. - 继承RuntimeException:是一个运行期异常,无需处理,交给虚拟机处理(中断处理)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/710889/1580825510865-71b4d7e9-41fd-4af2-aa7b-3b21b0459d5c.png#align=left&display=inline&height=39&name=image.png&originHeight=39&originWidth=1078&size=89026&status=done&style=none&width=1078)