课程内容:
-
什么是异常?
-
为什么要处理异常?
-
如何处理异常?
什么是异常?
-
Java当中所有“问题”的体系结构
Throwable
[可以向外抛出的]
Error Exception
[错误] [异常]
RuntimeException
[运行时异常] -
什么是异常?
异常 = Exception = 例外
指程序运行过程当中出现的例外情况而已...
-
关于报错 有三种不同层级的错误
1.编译报错
2.编译通过 运行报错 OutOfMemoryError
3.编译通过 运行也不报 就是数据都不对 -
最常见的运行时报出的Error
OutOfMemoryError
-
Error(错误) 和 Exception(异常) 的区别:
Error 通常是指由于[硬件环境]或者[系统原因]导致的
相对较严重的问题 通过编码无法解决的问题
Exception 就是指运行过程当中出现的例外情况而已
相对较轻 -
运行时异常和非运行时异常的区别:
非运行时异常 在编译的时候就必须给出处理方案
否则编译无法通过
它们直接继承自Exception
运行时异常 编译的时候不要求给出处理方案
编译能够直接通过 问题会在运行时直接体现出来
它们会继承自RuntimeException -
时至今日 我们见过的运行时异常 : 11个
常见的运行时异常有哪些?
1+2+3+4+1+2
1: 运算符涉及到的①
ArithmeticException => 算术异常
2: 数组涉及到的②
NegativeArraySizeException => 负数数组大小异常
ArrayIndexOutOfBoundsException => 数组索引值超出边界异常
3: 字符串涉及到的③
NullPointerException => 空指针异常
StringIndexOutOfBoundsException => 字符串索引值超出边界异常
NumberFormatException => 数字格式异常
4: 集合涉及到的④
IllegalArgumentException => 非法参数异常
IndexOutOfBoundsException => 索引值超出边界异常
IllegalStateException => 非法状态异常
ConcurrentModificationException => 并发修改异常
5: 引用数据类型转换涉及到的①
ClassCastException => 类造型异常
6: 线程涉及到的②
IllegalThreadStateException => 非法线程状态异常
IllegalMonitorStateException => 非法锁标记状态异常 -
时至今日 我们见过的非运行时异常 : 3个
//CloneNotSupportedException => 不支持克隆异常
//IOException => 输入/输出(写读)异常
//Runtime.getRuntime().exec("shutdown -s -t 10");
//AWTException => 抽象窗口异常
//Robot bot = new Robot();
//bot.mouseMove(400,300);
为什么要处理异常?
A.非运行时异常如果不做处理编译都无法通过
B.一旦程序(线程)运行过程当中出现未作处理的异常
虚拟机将直接中断该程序(线程)的执行
如何处理异常?
-
处理Sun公司的异常
1.抛还上级 throws
throws 用在方法签名的最后
用于表达 本方法当中出现指定种类的异常
方法当中不做处理 抛还给调用的上级进行处理
足以解决A 无力解决B
2.自行处理 try catch finally
try{
可能出现异常的语句;
}catch(要捕获的异常类型 异常代号){
对捕获到的异常进行处理
0.隐瞒不报
1.简要的审 异常代号.getMessage();
2.详细的审 异常代号.printStackTrace();
3.谎报 throw new XxxxException();
}finally{
无论是否出现异常 最终都要执行的操作
通常是释放和关闭资源的操作
}
*: 一个try后面可以跟上多个catch分支
但是只能前小后大或者并列关系
总之不能前者包含后者 否则报错
*: JDK7.0之前 如果捕获到不同异常要做相同的处理
也需要把catch分支写多次
JDK7.0开始支持多重catch
一个catch分支捕获多种类型
catch(类型1 | 类型2 e)
*: finally当中永远不该出现return语句
否则try catch当中的return
就都失去意义了 -
主动制造异常
1.如何在本没有异常的情况下 主动制造异常出现的场景
throw
用在方法体当中
在程序本没有异常的情况下 主动制造异常出现
[没事找事型]
*: throw 和 throws 的区别
throw 用于在方法体当中本没有异常的时候 主动制造异常
throws 用于方法签名后指明本方法中不做处理 需要抛给上级处理的异常
2.如何自定义异常?
1>.自己开发一个类 选择继承 Exception / RuntimeException
非运行时异常 / 运行时异常
2>.在其构造方法的首行使用 super()指定异常描述信息
class IllegalMonthException extends RuntimeException{
public IllegalMonthException(){
super("指定月份不合法");
}
} -
Plus1:
当类体当中某个静态变量
是通过调用某个有异常声明的方法完成赋值的时候
我们不能在类体当中直接try catch
也不能在类的签名后面throws
此时如果想要通过编译 就只能借助: 静态初始化块
在静态初始化块当中 可以使用try catch
class X{
static int a;//静态变量
static{
try{
a = getLuckyNumber();//异常声明的方法
}catch(Exception e){
e.printStackTrace();
}
}
}
*: 如果是个非静态变量呢?
可以使用非静态的初始化块 或者 构造方法 -
Plus2:
如果父类方法没有任何throws声明
子类的方法在覆盖它的时候 能不能向外抛出异常呢?
可以 但是只能抛出运行时异常
这样的行为是没有任何意义的
因为Java当中的每个方法默认都抛出所有的运行时异常
相当于 每个方法签名后面都有看不到的throws RuntimeException -
Plus3:
当程序代码逻辑当中出现连续的多行有异常声明的操作时
我们想要无论前者执行是否成功 后者都要尝试执行
此时就必须在try catch finally的finally当中
嵌套使用try catch
我们把这种语法称之为 连环try -
Plus4:
为了进行异常处理而添加的try catch 是有{}存在的
而这大括号同样能够控制变量的作用范围
如果想要在下文程序当中 依然使用这个变量
就必须把它的定义 拿到try前面去 并且以默认值赋值
在try{}当中 只做重新赋值 不做变量定义操作 -
Plus5:
在某些场景下 学会使用try catch 代替传统的分支判断
会有奇效
[下周五要用哦!]