异常
概述
- 异常就是程序出现不正常的情况
- 程序在执行过程中,出现的非正常的情况,最终会导致JVM非正常停止
- java有一套独立的异常处理机制,在遇到异常时,程序会抛出一个封装了错误信息的异常对象
异常的处理
JVM默认处理方案
- 如果程序出现问题且没有任何处理,最终JVM会默认处理
- 程序停止执行
- 把异常的名称,异常原因及异常出现的位置等信息输出在控制台 :::
try…catch捕捉异常
概述
- 为了提高程序的健壮性,通常需要对异常进行捕捉和处理
格式
- 一旦出现异常,try{}中的代码将停止执行,跳转到对应的catch(){}中继续执行
-
使用注意
try中没遇到问题不会执行catch中的代码
- try中遇到问题会中断执行跳转到catch中的代码
- 没有捕获的异常会抛给上层调用者,如果没有捕捉处理会传给虚拟机导致程序停止
- 多个catch的异常不能相同
- 若catch中多个异常之间有字符类异常的关系,那么子类异常要在上面的catch处理,父类异常在下面的catch处理
- 如果出现异常,只会执行一个catch
小结
- 捕获并处理可能出现的异常
- 好处:能让代码继续往下运行 :::
Trowable
Throwable中提供了查看异常信息的常用方法:
- public void printStackTrace()把异常的详细信息显示在控制台。
- public String getMessage()返回此异常的简单描述信息
- public String toString()返回此异常的类型和简单描述信息 :::
finally代码块
概述:
- 因为异常会引发程序跳转,导致某些语句执行不到,而有一些特定的代码无论异常是否发生都需要执行。
- finally代码块就可以解决这个问题,在finally代码块中的代码一定会被执行。
- try{
- //可能出现异常的代码
- }catch(异常类名 变量名){
- //处理异常的代码
- }finally{
- //必须执行的代码
- //(数据库连接的关闭,IO流关闭,锁的释放)
- }
说明
- 不管是否发生异常,finally代码块都会被执行
- 因此可以在finally代码块中执行关闭连接、关闭文件和释放线程锁的操作 :::
异常处理-throws
概述
- 当一个方法内部产生异常,而方法无法做出处理时,可以在该方法的头部声明这个异常,把异常交给调用者进行处理。(相当于上报异常,做免责声明)
格式
- 修饰符 返回值类型 方法名(参数列表) throws 异常类名1,异常类名2{ }
- 注意:throws关键字可以声明抛出多个异常,多个异常使用逗号隔开。
使用场景
- 当前方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理,如果调用者也不知道如何处理,那就继续向上声明抛出异常,以此类推直到main方法
- 如果 main 方法也不知道如何处理这种类型的异常,也可以使用 throws 声明抛出异常,该异常将交给 JVM 进行默认处理
方法重写时的注意
- 当进行方法重写时,子类重写的方法throws的异常的范围不能大于父类方法的异常范围
- 父类方法没有声明抛出编译时异常,子类重写的方法也不能抛出编译时异常,只能捕捉
- 建议重写的方法声明的异常和父类方法保持相同即可
结论
- 对可能出现异常的方法进行异常声明
- 告知调用者某个方法可能有问题,方法自身没有进行处理,而是让调用者去处理。 :::
throw关键字
概述
Java中提供了throw关键字,可以在程序运行过程中,抛出某种特定的异常
格式
-
注意
-
意义
在方法中,当传递的参数有误,程序没有运行下去的意义时,可以直接抛出异常,结束方法
-
throw与throws的区别
throws
是异常的处理方式之一,在方法定义时进行声明
- 表示声明异常,告知调用者,该方法有可能会出现这样的异常
throw
- 是产生一个异常的关键字,用在方法体内部
- 表示创建并抛出一个异常对象,throw与return有一样的效果,执行了throw之后,方法调用会结束 :::
自定义异常
概述
- JDK提供的异常虽然比较多,但是不一定符合我们的需求
- 此时我们可以根据自己的业务来定义异常类。例如年龄负数问题,考试成绩负数问题
步骤
- 定义异常类
- 写继承关系
- 空参构造
- 带参构造
存在意义
就是为了让控制台的报错信息更加的见名之意。 :::
public static void main(String[] args) {
try {
/*int arr[] = null;
System.out.println(arr.length);*/
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date parse = format.parse("2000-07-06");
System.out.println(parse);
//System.out.println(10/0);
}catch (NullPointerException e) {
System.out.println("空指针异常");
}catch (ParseException e) {
System.out.println("解析异常");
}catch (Exception e) {
System.out.println("未知异常");
}
}
public static void main(String[] args) {
try {
int[] arr = new int[0];
System.out.println(arr[1]);
}catch (Exception e) {
//把异常详细信息写到控制台上,便于程序员修改
e.printStackTrace();
//返回此异常的简单描述信息
System.out.println(e.getMessage());
//返回此类异常的类型和简单的描述信息
System.out.println(e.toString());
//System.out.println(toString);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入日期(yyyy-MM-dd)");
String str = sc.next();
try {
date(str);
}catch (ParseException e) {
System.out.println("输入错误");
}
}
public static void date(String str) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date parse = format.parse(str);
System.out.println(parse);
}
```java public static void main(String[] args) { Student stu = new Student(); Scanner sc = new Scanner(System.in); System.out.println(“请输入年龄:”); int age = sc.nextInt(); stu.setAge(age); System.out.println(stu.getAge()); }
class Student { private int age;
public void setAge(int age) {
if (age >= 0 && age <= 150) {
this.age = age;
} else {
throw new RuntimeException("输入错误");
}
}
public int getAge() {
return age;
}
}
```java
//自定义编译时异常
public class WrongAgeException extends Exception{
public WrongAgeException() {
}
public WrongAgeException(String message) {
super(message);
}
}
//自定义运行时异常
public class WrongAgeException02 extends RuntimeException{
public WrongAgeException02() {
}
public WrongAgeException02(String message) {
super(message);
}
}
private int age;
//调用自定义编译异常
public void setAge1(int age) throws WrongAgeException {
if (age >= 0 && age <= 150) {
this.age = age;
} else {
throw new WrongAgeException("年龄异常");
}
}
//调用自定义运行异常
public void setAge2(int age) {
if (age >= 0 && age <= 150) {
this.age = age;
} else {
throw new WrongAgeException02("年龄异常");
}
}