异常Exception
java具备健壮性:
1. GC 内存 保证内存够用的 回收无用对象
2. 异常处理的机制: 对异常的处理 不影响其他代码的正常执行
在编码期间 或者 程序运行期间 遇见了很多不正常的现象 称为错误 Error或者异常 Exception。
// System.out.println(3/0);//java.lang.ArithmeticException: / by zero
//NPE ClassCastException ArrayIndexOutOfException
// int[] array = new int[1024*1000*1000];//java.lang.OutOfMemoryError: Java heap space 内存溢出的错误
1. 有共同的父类 Throwable
2. 处理不正常的现象
错误: 无法处理 程序只能终止
异常: 可以修复的 可以处理的
Throwable
1.构造
Throwable(String message) 异常信息的字符串
Throwable(String message, Throwable cause) 异常信息传递
Throwable(Throwable cause)异常信息传递
2.功能方法
String getMessage() 获得详细异常字符串
void printStackTrace() 将异常日志打印输出到控制台
1. 异常体系
==编译时异常(检测到异常), 必须要处理 ===
运行时异常 (程序运行期间出现的问题 )----> 程序员本身在开发功能的时候 逻辑问题 —> jvm不管 不做任何处理
提前预判----> 用户
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rzW5r02k-1607389684471)(20201204104422.png)]
2.处理异常
不允许对任何运行时异常执行任何方式的处理 因为程序出现运行时异常 是程序员本身逻辑问题导致的。 应该提前预判避免出现运行时。
2.1 捕获异常
try…catch…finally 真正处理异常的方式
try{
//有可能会出现异常的程序
}catch(异常类型 异常对象){
//修复
//对异常信息处理操作
}[finally{
//不管程序是否出现异常 肯定会执行代码
//释放资源
}]
运行时异常为例:
索引越界,,,,
java.lang.ArrayIndexOutOfBoundsException: 3
at com.javasm.exception1.ExceptionDemo1.main(ExceptionDemo1.java:29)
肯定会执行的代码。。。。。
1
2
3
//异常机制
int[] num = {1, 2, 3};
try{
System.out.println(num[3]);
//有可能调用他人写的方法
}catch (RuntimeException e){
//修复了
//处理了异常
System.out.println("索引越界,,,,");
//调用e对象的功能方法
// System.out.println(e.getMessage());
e.printStackTrace();
}finally {
System.out.println("肯定会执行的代码。。。。。");
}
//遍历数组元素
for (int i : num) {
System.out.println(i);
}
}
public static void main(String[] args) {
int[] num = {1, 2, 3};
Scanner input = new Scanner(System.in);
try {
System.out.println(str.equals("hello"));//NPE
//异常之后的逻辑 就不执行了
System.out.println(num[3]);//越界
} catch (NullPointerException e) {
//这个异常到底是什么? 模糊
e.printStackTrace();
} catch (ClassCastException c) {
} catch (RuntimeException e) {
} //从小到大 执行catch
finally {
input.close();
//io
}
for (int i : num) {
System.out.println(i);
}
编译时异常
public static void main(String[] args) {
String borrowTime = "2020-12-04";
String returnTime = "2020-12-04 14:00:00";
long duration = getMoney(borrowTime, returnTime);
System.out.println("duration:" + duration);
}
public static void a() {
getMoney("", "");
}
private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";
private static long getMoney(String borrowTime, String returnTime) {
if (borrowTime == null || returnTime == null) {
throw new NullPointerException("参数不能为null");//遇见throw 程序结束
}
// Objects.requireNonNull(borrowTime);
// Objects.requireNonNull(returnTime,"");
//字符串不能执行算术运算---> 数值型
//字符串的时间数据 与 Date类型的数据相互转换
//1. str 转 Date 一定要求str的数据内容 >= pattern的格式要求
//pattern: 具体的日期格式 yyyy-MM-dd HH:mm:ss
SimpleDateFormat format = new SimpleDateFormat(PATTERN);
//java.util.Date 日期类 java.text.SimpleDateFormat 格式化日期
//为什么爆红? 检测到的异常 编译时异常 必须处理异常
Date borrowDate = null;
Date returnDate = null;
try {
borrowDate = format.parse(borrowTime);
returnDate = format.parse(returnTime);
} catch (ParseException e) {
e.printStackTrace();
System.out.println("字符串的数据肯定与pattern格式要求不符的");
}catch (Exception e){
}
//肯定要转到数值型的数据类型上执行运算
long time1 = borrowDate.getTime();//当前日期对象毫秒数
long time2 = returnDate.getTime();//当前日期对象毫秒数
return Math.abs((time1 - time2) / 1000 / 3600);
}
2.2 抛出
throws 处理异常一种方式 没有处理 消极处理 踢皮球
语法: 在方法的定义后面 声明抛出具体的异常类
public void demo() throws ArithmeticException,NullPointerException{
//声明抛出具体的异常类 对运行时 没有任何意义 等同于没写
}
//禁止这样编写
public static double divide1(int num1, int num2) throws ArithmeticException {
return num1 / num2;
}
public static void main(String[] args) throws ArithmeticException{//jvm
//main调用了divide1
System.out.println(divide1(1, 0));
System.out.println("jhdhhfdfd");
}
2.3 在catch具体的处理方式
try {
borrowDate = format.parse(borrowTime);
returnDate = format.parse(returnTime);
} catch (ParseException e) {
// e.printStackTrace();
// System.out.println("字符串的数据肯定与pattern格式要求不符的");
//该如何处理异常对象?
//e.printStackTrace();
//部署服务器: 写到日志文件中 Log4j self4j log4j2 logback
//Logger
// log.info();
// log.debug();
//return 数据; 在页面展示
//异常信息传递: Caused by: 具体的异常信息 将异常对象 传递给 级别高的异常对象里面 throw
try {
throw new Exception(e);
} catch (Exception e1) {
//处理e1
e1.printStackTrace();
}
}
3. throw
控制执行流程。 选择抛出具体的异常对象 throw new 异常类的构造();
public static String str;
public static double divide(int num1, int num2) {
// if (str == null) {
// throw (new NullPointerException("参数不能为null"));
// }
Objects.requireNonNull(str, "参数不能为null");
//除数不能为0
if (num2 == 0) {
//结束流程
throw new ArithmeticException("除数不能为0"); //遇见throw 程序停止
//异常信息会保存--->保存在文件里面 异常日志
//info debug warn error 保存不同的文件里面
}
return num1 / num2;
}
4. 自定义异常类
根据业务实现功能: 支付: 用户余额不足 throw new NPE(“用户余额不足”)
private static int balance = 2000;//用户余额
public static void pay(int totalMoney) {
/* try {
if (balance < totalMoney) {
throw new UserBalanceException(1001, "用户余额不足,无法支付");
}
} catch (UserBalanceException e) {
//log4j
e.printStackTrace();
// System.out.println(e.getCode());
// System.out.println(e.getMsg());
return;
}*/
// try {
// if (balance < totalMoney) {
// throw new UserBalanceException(1001, "用户余额不足,无法支付");
// }
// } catch (UserBalanceException e) {
// e.printStackTrace();
// }
balance -= totalMoney;
System.out.println("支付成功,支付了" + totalMoney);
System.out.println("用户余额剩余:" + balance);
}
// throw new UserBalanceException(1001, “用户余额不足,无法支付”);
// }
// } catch (UserBalanceException e) {
// e.printStackTrace();
// }
balance -= totalMoney;
System.out.println("支付成功,支付了" + totalMoney);
System.out.println("用户余额剩余:" + balance);
}