Java学习笔记——异常和断言
Java学习笔记——异常和断言
异常
异常就是在程序运行的过程中所发生的不正常的事件,它会中断指令的正常执行。
- Java提供异常类来表示程序运行中发生的异常
异常分为2大类 - Error:描述了Java运行系统中的内部错误以及资源耗尽错误
唯一的解决方法:尽力使程序安全地终止 - Exception:程序中需要关注的
运行时错误(RuntimeException):在 Java 虚拟机正常运行期间抛出的异常,由程序错误导致。 Java编译器允许程序中不对这类异常做出处理。
受检异常:EOFException,FileNotfoundException(文件未找到异常)
非受检异常:ArithmeticException(运算条件异常),NullPointerException(空指针异常),IndexOutOfBoundException(索引超出边界异常) - 解决方法——异常处理
对于异常Java中提供了两种常见的方式:
–捕获异常
–抛出异常
捕获异常(try—catch—finally)
若当前方法有能力处理异常,就捕获并处理它
try {
– 接受监视的程序块,在此区域内发生的异常,
– 由catch中指定的程序处理;
}catch(要处理的异常种类和标识符) {
– 处理异常;
}
try、catch处理流程
- try语句块中没有抛出任何异常
– 程序会跳过catch子句 - try语句块中抛出了catch子句中说明的异常
– 程序跳过try语句块中的其余代码
– 程序执行catch子句中的异常处理代码
打印结果:受监视代码块 执行完成
多重异常
一段代码可能会生成多个异常。
当引发异常时,会按顺序来查看每个 catch 语句,并执行第一个类型与异常类型匹配的语句。
执行其中的一条 catch 语句之后,其他的 catch 语句将被忽略。
使用多重 catch 语句时,异常子类一定要位于异常父类之前。
一个catch可以捕获多个异常,多个异常类型之间用“|”分隔开。
只有1个异常类型的标识符。
try {
i = a / b;
System.out.println("执行代码块");
} catch (IndexOutOfBoundsException | ArithmeticException e1) {
System.out.println("发生异常,请处理该异常!");
}
try语句块只能有一个,而catch语句块可以有任意多个
catch语句块紧跟在try语句块之后
finally语句块
- finally语句定义一个总是被执行的代码块,而不考虑是否出现异常
–无论try、catch是否执行,finally必定执行 - 不执行finally语句块的特殊情况
–在执行finally之前首先执行了“System.exit(0);”
无 catch 时 finally 必须紧跟 try
catch 与 finally 不能同时省略
try、catch 和 finally 语句块之间不能插入任何代码(注释除外)
抛出异常(throw、throws)
若当前方法没有能力处理异常,则只需抛出异常,交由方法调用者来处理。
一个方法不处理它产生的异常,而是沿着调用层次向上传递,由调用它的方法来处理这些异常,叫抛出异常。
-
声明异常使用throws关键字
语法:
–(修饰符)(方法名)([参数列表])[throws(异常类)]{…}
–例如:public void doA(int a) throws Exception1,Exception3{…} -
抛出异常: 语法:throw (异常对象);
如:throw new ArithmeticException(); -
如何抛出异常?
– 确定要抛出的异常类
• 系统提供的异常类
• 自定义的异常类
– 创建这个类的对象
– 将该对象抛出
打印结果:计算出错 -
throw和throws的区别
– throws语句用在方法声明后面,表示该方法会抛出哪些异常,使它的调用者知道要捕获这些异常。
– throw语句用在方法体内,表示抛出异常,是具体向外抛异常的动作,它抛出一个异常实例。
– throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常。
常见异常
- NullPointException:试图访问一个空对象时
– 常见解决方法:通过断点先确定哪个对象为空,再找到该对象没实例化的原因。 - NumberFormatException:试图把非数值转为数值时
–常见解决方法:根据控制台报的异常,找到出错的位置,看异常中数据是什么,确定是否有问题。 - ClassNotFoundException:当使用第三方Jar包时,可能由于没导入包,或者包的版本不对,而导致该包中没有程序员用到的类
常见解决方法:
–导入该包。
– 可以打开第三方Jar包,确认是否有该类,如果没有,可以更改包的版本。 - ArrayIndexOutOfBoundsException:访问超过数组或集合最大索引值的数据。
– 常见解决方法:通过断点等方法,找到是否是循环超出了范围等原因。 - ClassCastException:在集合中存入某对象,但是取出时却强转成其他对象
常见解决方法:
–通过加断点的方法,查看集合中存入的是什么对象,再和自己要强转的对象类型比较便知。
–泛型,已经限制了存入类型,就不会出现转换异常了。
自定义异常
程序员自定义异常必须是Throwable的直接或间接子类。
在程序中获得异常信息一般会调用异常对象的getMessage,printStackTrace,toString方法,所以自定义异常一般会重写以上三个方法。
断言
用于检查程序的安全性。
关键字assert、java.lang.AssertError类。
当需要在一个值为FALSE时中断当前操作的话,可以使用断言。
可看做是异常处理的高级形式,断言的布尔状态为true则没问题,如果为false,则抛出AssertError异常
- 两种形式
–assert Expression1
–assert Expression1:Expression2 - 断言在默认情况下是关闭的,启用断言验证假设须用到java命令的参数-ea。
使用断言的场合
- 可以在预计正常情况下程序不会到达的地方放置断言 :assert false
- 断言可以用于检查传递给私有方法的参数。
- 使用断言测试方法执行的前置条件和后置条件。
- 使用断言检查类的不变状态,确保任何情况下,某个变量的状态必须满足。
不使用断言的场合
- 断言语句不是永远会执行,可以屏蔽也可以启用。
- 不要再public的方法里面检查参数是不是为null之类的操作。
假如需要检查也最好通过if s = null 抛出NullPointerException来检查。 - 不要使用断言作为公共方法的参数检查,公共方法的参数永远都要执行。
- 断言语句不可以有任何边界效应,不要使用断言语句去修改变量和改变方法的返回值。