目录
视频教程传送门 -> https://www.bilibili.com/video/BV1Cv411372m?p=139
异常是程序在“编译”或者“执行”的过程中可能出现的问题
注意:语法错误不算在异常体系中
异常一旦出现,如果没有提前处理,程序就会退出JVM虚拟机而终止 =>
避免异常出现,同时处理可能出现的异常,让代码更稳健
异常体系
Error:系统级别问题、JVM退出等,代码无法控制。
Exception:java.lang包下,称为异常类,它表示程序本身可以处理的问题
RuntimeException及其子类:运行时异常,编译阶段不会报错。 (空指针、数组索引越界)
除RuntimeException之外所有的异常:编译时异常,编译阶段必须处理的,否则程序不能通过编译。 (日期格式化异常)。
异常的默认处理流程
默认会在出现异常的代码那里自动的创建一个异常对象:ArithmeticException。
异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给JVM虚拟机。
虚拟机接收到异常对象后,先在控制台直接输出异常栈信息数据。
直接从当前执行的异常点干掉当前程序。
后续代码没有机会执行了,因为程序已经死亡。
==> 默认的异常处理机制并不好,一旦真的出现异常,程序立即死亡
编译时异常的处理机制
编译时异常的处理形式有三种:
出现异常直接抛出去给调用者,调用者也继续抛出去
出现异常自己捕获处理
前两者结合,出现异常直接抛出去给调用者,调用者捕获处理
异常处理方式1 throws
方法 throws Exception{
}
这种方式并不好,如果异常最终抛出去给虚拟机将引起程序死亡
【例】
package com.test.d7_exception_handle;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
编译时异常的处理方式一
*/
public class ExceptionDemo01 {
{
public static void main(String[] args) throws Exception {
System.out.println("程序开始……");
parseTime("2011-11-11 11:11:11");
System.out.println("程序结束。");
}
public static void parseTime(String date) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(date);
System.out.println(d);
InputStream is = new FileInputStream("E:/book.jpg");
}
}
输出:
异常处理方式2 try…catch…
在出现异常的地方自己处理,并且出现异常后代码也不会死亡,不过上层调用者不能直接知道底层的执行情况。
try{
// 可能出现异常的代码!
}catch (Exception e){
e.printStackTrace(); // 直接打印异常栈信息
}
Exception可以捕获处理一切异常类型
IDEA中选中 -> Ctrl + Alt + T -> try/catch
【例】
package com.test.d7_exception_handle;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
编译时异常的处理方式二
在出现异常的地方自己处理,谁出现谁处理。
*/
public class ExceptionDemo02 {
public static void main(String[] args) {
System.out.println("程序开始……");
parseTime("2011-11-11 11:11:11");
System.out.println("程序结束。");
}
public static void parseTime(String date) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
Date d = sdf.parse(date);
System.out.println(d);
InputStream is = new FileInputStream("E:/book.jpg");
} catch (Exception e) {
e.printStackTrace(); // 打印异常栈信息
}
}
}
输出:
异常处理方式3 前两者结合
方法直接将异通过throws抛出去给调用者 -> 调用者收到异常后直接捕获处理
【例】
package com.test.d7_exception_handle;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
编译时异常的处理方式三
在出现异常的地方把异常一层一层的抛出给最外层调用者,
最外层调用者集中捕获处理(规范做法)
*/
public class ExceptionDemo03 {
public static void main(String[] args) {
System.out.println("程序开始……");
try {
parseTime("2011-11-11 11:11:11");
System.out.println("功能操作成功:)");
} catch (Exception e) {
e.printStackTrace();
System.out.println("功能操作失败:(");
}
System.out.println("程序结束。");
}
public static void parseTime(String date) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
Date d = sdf.parse(date);
System.out.println(d);
InputStream is = new FileInputStream("D:/book.jpg");
}
}
输出:
运行时异常的处理机制
运行时异常编译阶段不会出错,是运行时才可能出错的,所以编译阶段不处理也可以
建议在最外层调用处集中捕获处理即可