1. 异常概述、体系
1.1 什么是异常
- 异常是程序在“编译”或者“执行”的过程中可能出现的问题,注意:语法错误不算在异常体系中。
- 比如:数组索引越界、空指针异常、日期格式化异常等
1.2 为什么要学习异常
- 异常一旦出现了,如果没有提前处理,程序就会退出JVM虚拟机而终止
- 研究异常并且避免异常,然后提前处理异常,体现的是程序的安全,健壮性。
1.3 异常体系
- RuntimeException及其子类:运行时异常,编译阶段不会报错。(空指针异常,数组索引越界异常等)
- 除RuntimeException之外所有的异常:编译时异常,编译期必须处理的,否则程序不能通过编译。(日期格式化异常)。
2. 常见运行时异常
- 数组索引越界异常: ArrayIndexOutOfBoundsException
- 空指针异常 : NullPointerException。直接输出没有问题。但是调用空指针的变量的功能就会报错!!
- 类型转换异常:ClassCastException
- 数学操作异常:ArithmeticException
- 数字转换异常: NumberFormatException
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("程序开始。。。。。。");
/** 1.数组索引越界异常: ArrayIndexOutOfBoundsException。*/
int[] arr = {1, 2, 3};
System.out.println(arr[2]);
// System.out.println(arr[3]);
/** 2.空指针异常 : NullPointerException。直接输出没有问题。但是调用空指针的变量的功能就会报错!! */
String name = null;
System.out.println(name); // null
// System.out.println(name.length());
/** 3.类型转换异常:ClassCastException。 */
Object o = 23;
// String s = (String) o;
/** 4.数学操作异常:ArithmeticException。 */
// int c = 10 / 0;
/** 5.数字转换异常: NumberFormatException。 */
//String number = "23";
String number = "23aabbc";
Integer it = Integer.valueOf(number);
System.out.println(it + 1);
System.out.println("程序结束。。。。。");
}
}
3. 常见编译时异常
4. 异常的默认处理流程
- 默认会在出现异常的代码那里自动的创建一个异常对象:ArithmeticException
- 异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给JVM虚拟机
- 虚拟机街道异常对象后,现在控制台直接输出异常栈信息数据
- 直接从当前执行的异常点干掉当前程序
- 后续代码没有机会执行了,因为程序已经死亡
5. 编译时异常的处理机制
5.1 异常处理方式1:throws
- 用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者处理。
- 这种方式并不好,发生异常的方法自己不处理异常,如果异常最终抛出去给虚拟机将引起程序死亡
5.2 异常处理方式2:try…catch…
- 监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理。
- 这种方式还可以,发生异常的方法自己独立完成异常的处理,程序可以继续往下执行。
5.3 异常处理方式3:两者结合
- 方法直接将异常通过throws抛出去给调用者
- 调用者收到异常后直接捕获处理
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:/meinv.jpg");
}
}
6. 运行时异常的处理机制
- 运行时异常编译阶段不会出错,是运行时才可能出错的,所以编译阶段不处理也可以。
- 按照规范建议还是处理:建议在最外层调用处集中捕获处理即可。
public class Test {
public static void main(String[] args) {
System.out.println("程序开始。。。。。。。。。。");
try {
chu(10, 0);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
System.out.println("程序结束。。。。。。。。。。");
}
public static void chu(int a, int b){ // throws RuntimeException
System.out.println(a);
System.out.println(b);
int c = a / b;
System.out.println(c);
}
}
7. 自定义异常
7.1 自定义编译时异常
- 定义一个异常类继承Exception
- 重写构造器
- 在出现异常的地方用throw new 自定义对象抛出
作用:编译时异常是编译阶段就报错,提醒更加强烈,一定需要处理
7.2 自定义运行时异常
- 定义一个异常类继承RuntimeException
- 重写构造器
- 在出现异常的地方用throw new自定义对象抛出
作用:提醒不强烈,编译阶段不报错,运行时才可能出现