Throwable
java.lang.Throwable - 异常和错误的顶级的类
两个分支:
java.lang.Error - 错误 - 错误一旦发生,程序员是么有办法进行扭转的 - 不需要在代码中进行处理.
1-1. 子类VirtualMachineError虚拟机级别的错误
1-1-1. 子类java.lang.StackOverflowError 堆栈溢出 - 应用程序因为递归太深没有指定出口的时候.
1-1-2. 子类java.lang.OutOfMemoryError 内存泄漏 - [GC垃圾回收机制 - 后台自动回收垃圾对象]
java.lang.Exception - 异常 - 程序在运行的过程中发生了不正常的情况.
异常的分类
运行时异常[RuntimeException]都是非运行时异常的子类[Exception]
运行时异常 - 未检测异常
顶级的父类java.lang.RuntimeException
java.lang.NullPointerException - 空指针异常
java.util.InputMismatchException - 输入不匹配异常
Scanner sc = new Scanner(System.in); int n = sc.nextInt();//只能获取整数.但是输入了一个字符串"abc"
java.lang.ArithmeticException - 分母为0
java.lang.IllegalArgumentException - 非法参数异常
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 构造中的模板如果传入了一个非法模板
java.lang.IndexOutOfBoundsException - 下标越界异常 - 比如list.get(100);
5-1. java.lang.StringIndexOutOfBoundsException - 字符串下标越界异常
5-2. java.lang.ArrayIndexOutOfBoundsException - 数组下标越界异常
java.util.NoSuchElementException - 不存在此元素
LinkedList<Character> list = new LinkedList<>(); System.out.println(list.getFirst());//获取栈顶元素,但是栈顶没有元素
java.lang.ClassCastException - 类型转换失败异常
父类类型转换成子类类型之前,推荐先使用instanceof关键字进行类型的判断
非运行时异常 - 已检测异常
java.text.ParseException - 解析失败异常 - 字符串的模板和pattern不匹配
InterruptedException - 中断异常 - Thread.sleep(1000);
java.lang.CloneNotSupportedException - 不允许被clone.
当调用对象的clone方法,但是这个对象没有去实现java.lang.Cloneable接口
java.io.IOExcetion - IO流异常
4-1. java.io.EOFException - 已经读取到文件的末尾了.
4-2. java.io.FileNotFoundException - 文件找不到异常
java.sql.SQLException - SQL异常,比如程序中的sql语句要是写错了.
异常的处理方式
运行时异常不需要处理(也是可以处理的),只需要在编程的时候,注意一下验证/判断.稍微谨慎一点.
非运行时异常 - 编译期间就需要立即对其进行处理.处理的方式有俩种.一种是积极处理 - try..catch的方式
另外一种是消极处理.
积极处理方式
语法一 - try….catch….catch….finally
推荐使用到的 - 因为针对每种不同的异常进行单独的日志记录,单独的异常处理.
try{ //code.. //code.. }catch(异常类型1 e1){ }catch(异常类型2 e2){ }finally{ //无论是否出现异常,都会执行 } 注意:上方的异常类型不能是下方的异常类型的父类.
语法二 - jdk7.0提供的新的写法
try{ //code... //code... }catch(异常类型1 | 异常类型2){ //... }
语法三 - 简单粗暴
try{ //.... }catch(异常总父类){ //... }
消极处理
比如在某个方法中某些代码出现了非运行时异常,那么在自己方法的内部”不着急”去积极处理.而是把这个异常抛出去了.
为了自己不处理,而是抛出去? - 因为这个方法有可能会被反复在其他地方调用 - 原则:谁调用,谁负责最终处理.
原则谨记 - 不要把异常抛给main方法,等同于把异常抛给jvm,等同于一旦出现异常,程序就会崩溃.
直接在方法的签名[声明]上使用throws关键字+异常类型1,异常类型2
在方法体中使用throw+异常对象
public static void d(int n) throws FileNotFoundException { if(n==0){ //System.out.println("异常的描述...."); //throw + 运行时异常对象,不需要在方法的签名上抛出异常 - 本身运行时异常就不需要处理呀! //throw new RuntimeException("发生异常了..."); //throw + 非运行时异常 配合 必须要在方法的签名上throws+非运行时异常类型 throw new FileNotFoundException("文件不存在!"); } System.out.println("n:"+n); }
笔试题 - throws和throw有什么区别
笔试题1
try{
//code...
//code..
return;//结束整个方法
}catch(异常类型 e){
}catch(异常类型 e){
}finally{
//无论是否出现异常,都会执行
}
假设try{}中没有任何异常发生,所有的code都会顺利执行.
1. finally中的代码执行否? - 肯定会执行
2. return语句是在finally块之前执行还是之后执行? - 之后
笔试题2
package tech.aistar.day12.exception;
/**
* 本类用来演示: 笔试题
*
* @author: success
* @date: 2021/8/4 3:23 下午
*/
public class FinallyDemo {
public static void main(String[] args) {
System.out.println(test());//1
System.out.println(change());//A{age=200}
}
//finally中修改了基本数据类型
public static int test(){
int i = 0;//①
//try可以直接和finally一起使用....
try{
//此处将i自增后的结果缓存起来了.并且这个缓存的结果就是作为最终返回出去的一个结果 - 对待基本数据类型.
return ++i;
}finally {
++i;//③
System.out.println("i:"+i);
}
}
//finally修改了对象类型的属性
public static A change(){
A a = new A();
try{
a.age = 100;
//return是在finally之后执行
return a;
}finally {
//对待对象类型 - finally中的修改对象的属性值,是对return的结果是产生了影响的.
a.age = 200;
}
}
}
class A{
public int age = 18;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("A{");
sb.append("age=").append(age);
sb.append('}');
return sb.toString();
}
}
笔试题3
final和finally和finalize三者之间的区别? - 一点关系都没有
final
a. 修饰的局部变量一旦赋值成功,不可改变
b. 修饰的属性一旦赋值成功,不可改变
c. 修饰的类不可被继承
d. 修饰的方法不可被重写
finally
a. 一般是和try..catch搭配使用的.try块中无论是否出现异常,finally块中代码都会执行
b. finally块中一般写的是释放或者关闭资源的代码
finalize - Object类中提供的方法
a. 当GC想去回收一个垃圾对象之前,会去调用这个对象的finalize方法.是由JVM去调用.
b. 该方法未必一定会被调用得到.
自定义异常
项目中其实是专门包exception - 专门自定义自己的异常[大量的]
jdk内置的异常不够用,不符合实际的业务场景.
步骤
- 写一个异常类继承java.lang.Exception
- 提供父类的5个构造方法即可
思考为什么要自定义异常
System.out.println("余额小于0"); throw new BalanceLtZeroException("余额小于0!");
场景:有的时候访问某些网站的时候 - 跳转到一个友好的页面 - 显示比如服务器正在维护/升级…
我们应该提供一个
异常处理器
- 会监控软件程序在整个项目运行的过程中发生的一切异常.一旦它发现了某个地方产生了异常,那么它就会对这些异常进行一个日志记录,然后再让程序跳转到一个友好的界面.
SpringMVC/SpringBoot -
异常处理器
- 只认识异常.
复习
- 重点围绕OO - 面向对象
- 三大特性 - 封装,继承,多态
- 抽象类和接口区别
- 四种访问修饰符的作用权限
- 方法的重载和方法的重写
- 单例 - 双重检测锁
- 简单工厂
- static关键字的作用 - static练习
预习
泛型
IO流 - 大头
并发编程 - 多线程 - 大头中的大头 - 最难的最难的最难的
反射技术 - 看懂框架的源码[反射技术 + 设计模式]
动态代理 - [jdk动态代理 + cglib动态代理]
枚举类型