A.异常的定义
异常分为错误和异常
现实生活中的案例:
相当于一个人生病了,分为:
可以治愈的:
——小病(牙疼、感冒)
——大病(发烧、做手术)
不能治愈的:艾滋病、癌症晚期
B .Java的异常体系
1.java异常体系包含在java.lang包中,lang包是不用导入的。
2.Java异常体系包括:
——Throwable(实现类描述java的错误和异常):
——Error(错误):一般来说无法通过代码来控制
在一个合理的应用中不能截获的严重问题,大多数都是反常的情况,错误很难处理,所以一般的开发人员是无法处理这些错误的。比如堆内存溢出。
——Exception(异常):
——运行时异常(比如空指针异常)
指的是代码在运行过程中出现的异常信息,会被java虚拟机(JVM)所捕获,会告诉开发人员异常产生的原因和处理的建议。比如空指针异常。
——非运行时异常(是需要声明的,它会提前告知可能出现的异常)
C.异常处理机制
1.由JVM来捕获:
如果由JVM捕获的话,那么程序员无法控制该异常,只能结束当前程序。
2.自行捕获:
try{
把有可能出现异常的代码块放到我们的try中
}catch(处理异常1,它会根据异常的类型来捕获,处理哪些异常){
处理该异常的方式
}catch(处理异常2){
多个catch是有优先级的,如上面的已经捕获异常,下面的不做处理
}
PS:
1.程序中有多个语句可能发生异常时,可以都放在一个try语句中,并匹配相对应的catch语句。
2.如果异常被catch捕获到,那么它就会执行完本身的catch代码块,再执行后续的代码块,如没有匹配到,则最终交给JVM处理。
3.try代码块中,一旦出现异常信息,只会处理第一条异常信息出现的位置,剩余的代码块不做处理。
4.可以使用多态处理机制,用这些异常的父类来进行接收。
3.使用异常的注意事项
1.异常的执行顺序是从上到下的。
2.如果多个异常,存在父子类关系的时候:
1.子类异常在上,父类异常在下,编译和运行都没问题;
2.父类异常在上,子类异常在下,编译就不能通过(因为父类可以处理子类的异常,那么子类的异常就处理不到,写了也没意义,造成代码冗余);
3.编写多个异常时,务必按照先子类后父类的顺序进行catch处理。
D.非运行时异常
就是在编写代码时就告诉我们的JVM虚拟机,有可能会出现什么异常,并且进行声明,这个异常必须处理(或者抛出),如不处理会报编译错误。
E.自定义异常
描述:程序员可以将程序出现的特有异常进行封装,按照程序员设定的信息作为信息展示,便于后期的日志维护。
1、创建一个异常类,专门用于处理异常,该类需要继承异常的父类Exception,然后实现我们的代码。
package day0708;
/**
* @author WJ
* @date 2021年7月8日 上午9:54:28
*
* @description:自定义异常类,该类用于处理缺失usb接口
*/
public class NoUSBException extends Exception {
public NoUSBException() {
// TODO Auto-generated constructor stub
}
public NoUSBException(String message) {
super(message);
}
}
package day0708;
/**
* @author WJ
* @date 2021年7月8日 上午9:57:42
*
* @description:
*/
public class USBTest {
public static void main(String[] args) {
USBTest t = new USBTest();
try {
t.usb(null);
} catch (NoUSBException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
System.out.println(e.toString());
System.out.println(e.getMessage());
}
}
public void usb(String msg) throws NoUSBException {
if (msg == null) {
throw new NoUSBException("没有匹配的USB!");
}
System.out.println(msg);
}
}
【案例】模拟你在网吧上网,如果金额小于10元,则提示充值,否则正常使用(使用自定义异常)
思路:自定义一个异常,用于处理金额不足的异常信息
正常程序去执行上网操作,如果遇到异常,使用自定义异常提示信心
(和上面的代码相似)
F.finally关键字
1.基本语法
第1种书写方式:比较适合于既要处理异常信息,又要释放资源的代码;
举例:IO流、连接数据库、比方说在地铁站出站后要使用共享单车,如果只使用不归还,资源就会枯竭。
try{
}catch(){
}finally{
}
第2中书写方式:比较适用于都是运行时异常,且需要释放资源的代码;
举例:数据库连接超时等。
try{
}finally{
}
2.finally的使用技巧
a.首先该finally主要用于释放系统资源;
b.无论程序是否异常,代码都会执行finally,连return语句都不能停止finally运行;
c.是否可以组织finally永远都执行?只有一种情况,如果我们设置了System.exit(0),那么finally就不执行。(被迫不执行)
d.finally里面也可以嵌套try catch finally。
package day0708_01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author WJ
* @date 2021年7月8日 上午10:55:29
*
* @description:finally关键字
*/
public class FinallyTest {
public static void main(String[] args) {
FinallyTest t = new FinallyTest();
System.out.println(t.run());
}
public int run() {
// 读取硬盘中文件
FileInputStream fin = null;
try {
fin = new FileInputStream("E:\\ZTE—Java\\Code\\JavaSE\\a.txt");
// System.exit(0);//强制JVM退出,finally被迫不执行
return 1;// return也不能阻止finally的执行
} catch (FileNotFoundException e) {
System.out.println("没有找到该文件!");
} finally {
System.out.println("这是finally");
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
return 0;
}
}