① 异常:程序执行过程中的非正常情况,会导致JVM停止,异常是程序员可以解决的。
② 错误:严重的错误,程序员无法解决,只能修改代码。
Throwable
- Error
- Exception
- RuntimeException
# 异常他爹他儿子和他兄弟
① 运行时异常(RuntimeException)
在程序运行时产生的异常。这个我们可以不用管
② 编译时异常(除运行时异常以外的异常)
在编译时产生的异常,这个我们必须解决,不然程序无法执行。
① 某个方法出现问题
② JVM new 一个异常对象给异常发生的方法
③ 如果该方法不处理这个异常,会将这个异常抛给这个方法的调用者,一层层抛出,直至有人处理或抛给 main
④ main无法处理这个异常会抛给 JVM,JVM 会打印异常信息中断程序执行。
① 格式
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
② 表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(即将异常抛给调用者处理)
③ 注意
* 异常可以抛出多个
* 调用者若不处理异常也要将异常抛出
* 处理完异常后 JVM 终止程序,程序不能继续执行。
④ 示例
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class DemoException {
//抛出异常
public static void main(String[] args) throws ParseException {
//创建日期格式化对象
SimpleDateFormat pdf = new SimpleDateFormat("yyyy-MM-dd");
//格式不正确,产生编译异常
pdf.parse("2019年6月5日");
}
}
① 格式
try{
编写可能会出现异常的代码
}catch(异常类型 e){
处理异常的代码
}
② 对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式的处理
③ 注意
* try 和 catch不能单独使用
* 处理完异常后程序可以继续执行
④ 异常的一些方法
* public String getMessage()
获取异常的描述信息,原因(提示给用户的时候,就提示错误原因。
* public String toString()
获取异常的类型和异常描述信息(不用)。
* public void printStackTrace()
打印异常的跟踪栈信息并输出到控制台(默认)。
⑤ 示例
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DemoException {
public static void main(String[] args) throws FileNotFoundException {
//标识开始 main 方法
System.out.println("=============== " + new Date().getTime() + " main 开始 =================");
//创建日期格式化对象
SimpleDateFormat pdf = new SimpleDateFormat("yyyy-MM-dd");
//捕获异常
try {
//将文本解析为日期对象,格式不正确产生异常
Date date = pdf.parse("2019.06.04");
System.out.println(date);
} catch (ParseException e) {
//创建日期格式化对象
SimpleDateFormat p = new SimpleDateFormat("yyyyMMddHHssmm");
//将异常信息输出到以当前时间命名的文件中
e.printStackTrace(new PrintStream("C:\\Users\\Demo_Null\\Desktop\\" + p.format(new Date()) + ".java"));
}
//标识结束 main 方法
System.out.println("=============== " + new Date().getTime() + " main 结束 =================");
}
}
① 格式
try{
编写可能会出现异常的代码
}catch(异常类型 e){
处理异常的代码
}finally{
不论怎样都要执行的代码
}
② 在finally代码块中存放的代码都是一定会被执行的,一般用来释放资源。
③ 注意
* catch 和 finally 只能省略其中之一
* 除了推出 JVM(System.exit(0)) 之外,不论什么情况(包括 return ) finally 内的代码都要执行。
④ 示例
public class DemoException {
//抛出异常
public static void main(String[] args) {
//捕获异常
try {
//将文本解析为日期对象,格式不正确产生异常
Date date = pdf.parse("2019.06.04");
System.out.println(date);
} catch (ParseException e) {
//创建日期格式化对象
SimpleDateFormat p = new SimpleDateFormat("yyyyMMddHHssmm");
//将异常信息输出到以当前时间命名的文件中
e.printStackTrace(new PrintStream("C:\\Users\\Demo_Null\\Desktop\\" + p.format(new Date()) + ".java"));
}finally {
System.out.println("我处理了产生的异常");
}
}
}
① 多次捕获多次处理
try {
} catch (异常类型 e) {
}
try {
} catch (异常类型 e) {
}
try {
} catch (异常类型 e) {
}
② 一次捕获多次处理
try {
} catch (异常类型1 e) {
} catch (异常类型2 e) {
} catch (异常类型3 e) {
}
#注意:子类异常必须在父类异常前面处理
③ 一次捕获一次处理
try {
} catch (Exception e) {
}
① 格式
throw new 异常类型(参数);
② 用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
③ 示例
public class ThrowDemo {
public static void main(String[] args) {
//创建一个数组
int[] arr = new int[3];
int element = getElement(arr, 3);
System.out.println(element);
}
/*
* 根据 索引找到数组中对应的元素
*/
public static int getElement(int[] arr,int index){
//判断 索引是否越界
if(index<0 || index>arr.length-1){
/*
判断条件如果满足,当执行完throw抛出异常对象后,方法已经无法继续运算。
这时就会结束当前方法的执行,并将异常告知给调用者。这时就需要通过异常来解决。
*/
throw new ArrayIndexOutOfBoundsException("数组索引越界了!");
}
int element = arr[index];
return element;
}
}
① 自定义一个编译时异常必须继承 Exception
② 自定义一个运行时异常必须继承 RuntimeException
//定义一个错误分数异常
public class ErrorNumberException extends RuntimeException {
public ErrorNumberException() {
}
public ErrorNumberException(String message) {
super(message);
}
}
//定义一个学生类,学生(Student)都有学号,姓名和分数,分数不能为负数
public class Student {
private String name;
private long num;
private int score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getNum() {
return num;
}
public void setNum(long num) {
this.num = num;
}
public int getScore() {
return score;
}
public void setScore(int score) {
if (score < 0) {
//抛出错误分数异常
throw new ErrorNumberException("分数不能为负数");
} else {
this.score = score;
}
}
}
//定义一个测试类
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("韩梅梅");
stu.setNum(12345678910002L);
stu.setScore(-90);
}
}