Java学习日记15——异常处理
异常又称为例外、差错、违例,对应着Java运行错误的处理机制,基本写法是:
try{
语句;
}catch(Exception ex){
异常处理语句1;
}catch(Exception ex){
异常处理语句2;
}finally{//可有可无
最终异常一定执行语句;
}
简单解析:try中间的语句就是被监测执行语句,catch语句则是捕获异常,每个catch能捕获一种异常,然后对应的{}中放着如果出现错误该执行的异常处理语句。
Java在异常处理时,通常有一下几个情况:
抛出(throw)异常:向外抛出异常,也可以在内部进行处理
运行时系统在调用栈中查找:在抛出异常的位置开始查找,直到找到相应的处理语句为止。
捕获(catch)异常的代码。
异常分类
Error:JVM的错误
Exception:也就是一般意义上的异常
一般所说的异常都是指Exception及其子类。所以这里重点将Exception类:
构造方法是:
public Exception();
public Exception(String message);
Exception(String message,Throwable cause);
方法:
getMessage();//得到信息
getCause();//得到内部原因
printStackTrace();//显示调用堆栈的跟踪信息,可以展示出多层调用
多异常处理顺序
子类异常要排在父类异常的前面
finally语句无论是否有异常都会执行,即使其中有break,return等语句,在编译时也会被生成很多遍。
受检异常
受检异常就是明确要求进行语法处理,面对这种异常,两种做法:
1.要么捕获(catch)
2.要么抛出(throws):在方法签名后面用 throws xxxx来声明。
值得注意的是,在子类中,如果要覆盖父类的方法,且父类声明了throws异常,子类也可以使用throws异常。
自定义异常类
自定义异常类时,都是继承自Exception类及其子类,定义属性和方法,或者重载父类方法。
重抛异常:对于异常,不仅要进行捕获,还需要进一步将异常传递给调用者,以便于调用者也能感受这种异常。这是可以在catch语句或者finally语句中采取以三种方式:
1.将当前异常再次抛出:
throw e;
2.重新生成一个异常,并抛出:
throw new Exception(“some messages”);
3.重新生成一个异常,且包含当前异常的信息:
throw new Exception(“some messages”,e);可以使用e.getCause()获取内部异常
直接上例子:代码很好理解,建议阅读,是一个ATM的实现代码。
//文件:datasys.java
import java.util.ArrayList;
public class datasys{
private ArrayList<String> IDdata = new ArrayList<String>();
private ArrayList<Double> moneydata = new ArrayList<Double>();
public void readdata( String ID) throws IDexception{
int m = IDdata.size()+1;
for (int i=0;i<IDdata.size();i++) {
if (IDdata.get(i).equals(ID) && ID != null) {
m = i;
System.out.println(ID+"的余额为:"+moneydata.get(m)+"元");
}
}
if (m == IDdata.size()+1) {
throw new IDexception("查无此ID:"+ID);
}
}
public void writedata(String ID,double money) throws Wexception {
IDdata.add(ID);
moneydata.add(money);
}
public void savemoney(String ID ,double money) throws IDexception {
for (int i=0;i<IDdata.size();i++) {
if (IDdata.get(i) == ID && ID != null) {
moneydata.set(i, moneydata.get(i) + money);
}
else {
throw new IDexception("查无此ID");
}
}
}
public void withdowmoney(String ID ,double money) throws IDexception, bablanceexception {
for (int i=0;i<IDdata.size();i++) {
if (IDdata.get(i) == ID && ID != null) {
if (moneydata.get(i) - money>=0) {
moneydata.set(i, moneydata.get(i) - money);
}
else {
throw new bablanceexception("余额不足");
}
}
else {
throw new IDexception("查无此ID");
}
}
}
public void diaplay() {
for (int j = 0; j < IDdata.size(); j++) {
System.out.print(IDdata.get(j));
System.out.println(moneydata.get(j)+"元");
}
}
}
class IDexception extends Exception{//读取ID不存在的异常
public IDexception(String message) {
super (message);
}
}
class Wexception extends Exception{//输入异常
public Wexception(String message) {
super (message);
}
}
class bablanceexception extends Exception{//余额不足异常
public bablanceexception(String message) {
super (message);
}
}
//文件:ATM.Java
public class ATM {
public static void main(String[] args) {
datasys atm = new datasys();
try {
atm.writedata("张三", 2020);
atm.writedata("李四", 1010);
atm.writedata("王五", 3030);
atm.diaplay();
atm.readdata("张三");
atm.readdata("小陈");
} catch (Wexception e) {
e.printStackTrace();
}catch (IDexception e) {
e.printStackTrace();
}
}
}
执行的结果如下:
张三2020.0元
李四1010.0元
王五3030.0元
张三的余额为:2020.0
IDexception: 查无此ID:小陈
at datasys.readdata(datasys.java:14)
at ATM.main(ATM.java:12)
断言(assertion)
主要是用于程序代码的测试的一种手段,如果表达式正确,那么就正常执行,如果表达式不正确,那么就输出信息部分。如下格式:
assert 表达式:
assert 表达式:信息;
举个例子:
static double hy(double x,double y){
return Math.aqrt(x*x+y*y+1);//计算勾股定理故意写错+1
}
public static void main(Srting [] args){
assert hy(3,4) == 5: "算法有误"//这里运行就会因为结果不等于5而输出冒号后面部分
}
如果直接运行,那么在cmd中需要输入-ea才能使assert语句起作用,例如:
java -ea -classpath.Assertion
测试(JUnit)
JUnit测试框架,在现在的Java集成开发工具中一般都包含支持,在eclipse中分为两步:
建立测试程序:项目 - 右键-new-JUnit Test case
运行测试:项目 - 右键 -run as -JUnit Test
如此建立的测试函数会有@Test的标注。
调试
大致可以分为三类错误:
1.语法错误(Syntax error):编辑、编译器会发现
2.运行错误(Runtime error);异常处理机制
3.逻辑错误(Logic error):调试(debug)、单元测试(unit Test)
调试的三种手段:
1.断点:设置运行断点
2.跟踪:观察程序的执行顺序
3.监视:监视变量的改变情况
如果你对Java有兴趣,可以了解一下前面几期的基础知识!下面附上链接:
Java编程基础认知:Java学习日记1——基础认知
Java面向对象编程认识:Java学习日记2——面向对象编程认知
Java程序的基本结构认识:Java学习日记3——程序类型与构成认知
Java的输入输出方法总结:Java学习日记4——Java输入输出方法总结
Java的数据类型、变量、常量、运算符:Java学习日记5——数据类型、变量、常量、运算符、数组
Java学习日记6——类、字段、方法、this的使用:Java学习日记6——类、字段、方法、this的使用
Java学习日记7——类的继承、super使用规则:Java学习日记7——类的继承、super使用规则
Java学习日记8——修饰符:Java学习日记8——public、static、private、final、abstract、protected
Java学习日记9——接口(长文预警):Java学习日记9——接口(长文预警)
Java学习日记10——Java中的变量及其传递:Java学习日记10——Java中的变量及其传递
Java学习日记11——多态和虚方法调用:Java学习日记11——多态和虚方法调用
Java学习日记12——构造方法及其初始化、构造方法的执行过程——Java学习日记12——构造方法及其初始化、构造方法的执行过程
Java学习日记13——内部类和匿名类、以及垃圾回收机制——Java学习日记13——内部类和匿名类、以及垃圾回收机制
Java学习日记14——Lambda表达式以及一些高级语法——Java学习日记14——Lambda表达式以及一些高级语法