异常
编写程序的流程:编辑、编译、连接、运行。
不同的阶段会有不同的错误
- 编译阶段:语法
- 链接阶段:缺少外部包、外部库
- 运行阶段:语法错误、逻辑错误,代码设计思路问题
通过异常或断言来友好的提醒用户发生的问题
概念
异常:程序运行过程中,所发生的不正常的事件,会中断指令的正常执行。
原因
- 用户输入错误
- 设备错误
- 代码错误
- 磁盘空间不足
- ...
分类
- Erroe:Java运行系统中的内部错误、资源耗尽错误
- 解决:安全中止
- Exception:程序出错
- 运行时异常:正常运行期间抛出的异常,不处理
- 错误的类型转换
- 数组下标越界
- 访问空指针
- 其他异常:必须处理
- IO异常
- SQL异常
- 运行时异常:正常运行期间抛出的异常,不处理
后果
- 丢失用户数据
- 程序崩溃
异常处理机制
异常机制提供了程序退出的安全通道。
当出现异常后,程序执行的流程发生改变,执行相应的异常处理代码。
- 捕获异常
- 抛出异常
捕获异常
有能力处理异常,对异常进行捕获并处理。
try{
//接受监视的程序块
//发生异常后由指定的catch处理
}catch(处理异常类型){
//处理异常
}
执行流程
try
语句没有异常,catch
语句忽略try
语句发生异常,try
剩余语句块被忽略,执行catch
语句捕获异常进行处理
多重异常
一段代码可能发生多个异常。
处理方法一:
try{
//接受监视的程序块
//发生异常后由指定的catch处理
}catch(处理异常类型){
//处理异常
}catch(处理异常类型){
//处理异常
}
引发异常时:
- 按顺序对比
catch
语句,执行第一个匹配的catch
语句。 - 执行一条
catch
语句后,其他catch
语句被忽略。 - 异常子类一定要位于异常父类之前。
处理方法二:
try{
//接受监视的程序块
//发生异常后由指定的catch处理
}catch(处理异常类型|处理异常类型|处理异常类型|处理异常类型 标识符){
//处理异常
}
- 一个
catch
可以捕获多个异常。 - 多个异常类型用
|
隔开 - 只有一个异常类型的标识符
- 多个异常类型不存在父子继承关系
finally
finally语句定义一个总是被执行的代码块,而不考虑是否出现异常。
主要应用在资源回收上。
try{
//接受监视的程序块
//发生异常后由指定的catch处理
}catch(处理异常类型){
//处理异常
}fianlly{
//必定执行
//资源回收
}
特殊情况:在finally
之前执行System.exit(0);
,不执行finally
。·
规则与注意要点
- 没有
catch
时,finally
跟进try
catch
与finally
不能同时省略。不能只有try
try
、catch
、finally
语句块之间不能插入代码
优势
Java提供异常类,充分发挥类的可扩展和可重用性。
异常流程和正常流程代码分离,提高程序可读性,简化程序结构。
抛出异常
没有能力处理异常,抛出异常,让方法调用者处理。
不处理异常,沿着调用层次向上传递,由方法调用者处理。
语法
throws
是抛出异常的关键字声明。
//public void get() throws 异常类{}
//throw 异常对象;
throw new ArithmeticExption();
使用
- 确定要抛出的异常类
- 系统提供的异常类
- 自定义的异常类
- 创建这个类的对象
- 将对象抛出
throw
和throws
区别
throw
语句在方法声明后,表示方法会抛出哪些异常,让调用者了解并捕获。throw
语句用在方法体内,表示抛出异常。throws
表示出现异常的可能,不一定会发生- 执行
throw
则一定抛出了这种异常
异常注意事项
- 避免过大的
try
块,尽量一个try
块对应一个或多个异常 - 细化异常类型
catch
块保持一个块捕获一个异常,不能忽略异常- 能处理的异常不要抛出
try
、catch
不要参与控制流程,根本目的是处理程序的非正常情况
自定义异常
JDK提供的异常类型不能满足需求的时候,程序员可以自定义一些异常类
自定义异常必须是Throwable
的直接或间接子类
异常信息一般会调用异常对象的
getMessage
,
printStackTrace
,
toString
方法,所以自定义异常一般会重写以上三个方法
public class MyException extends Exception{
public String getMessage(){
//自定义代码
}
public String toString(){
//自定义代码
}
public void printStackTrace(){
//自定义代码
}
}
断言
断言可以是异常处理的高级形式。
值为FALSE时中断当前操作的话,可以使用断言。
使用
assert Expression1
assert Expression1:Expression2
public class Demo{
public static void main(String args[]){
Demo d = new Demo();
//调用方法测试
d.assertNow(true);
d.assertNow(false);
}
//断言
private void assertNow(boolean b){
//第一种
assert boo;
System.out.println("true condition");
//第二种
String s = null;
assert boo:s = "hello world";
System.out.println("true condition");
}
}
断言在默认情况下是关闭的,启用断言验证假设须用到java命令的参数-ea
在Eclipse中的run configuration中添加默认参数-ea
适用场合
- 在可预计正常情况下程序不会到达的地方放置断言,assert false
- 断言可以用于检查传递给私有方法的参数。
- 使用断言测试方法执行的前置条件和后置条件
- 使用断言检查类的不变状态,确保任何情况下,某个变量的状态必须满足条件
博客相关java项目:查看Github项目
对应github项目:YiChangDuanYan
导入项目的方法: Java基础——Java如何导入本地项目