一、异常
1.1 异常概述
- 程序运行过程中出现了不正常【报错】的情况
1.2 异常处理的必要性
- 任何程序都可能存在未知的异常,可能造成不必要的损失
1.3 异常的分类
Throwable
Throwable类是 Java 语言中所有错误或异常的超类。- 只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java
throw语句抛出。 - 类似地,只有此类或其子类之一才可以是
catch子句中的参数类型。 - 两个子类的实例,
Error和Exception,通常用于指示发生了异常情况。
Error
- 用于指示合理的应用程序不应该试图捕获的严重问题。
- 虚拟机错误、配置错误、线程死亡错误、、、
- 无法通过代码处理的异常
Exception
- 它指出了合理的应用程序想要捕获的条件。
- 开发者能处理 并且 需要处理的异常
- 索引越界、空指针异常、算术运算异常、类型转换异常、、、
- 因为代码或者配置产生的异常,需要处理
1.4 异常的产生
- 虚拟机抛出
- 手动抛出
public class Demo02 {
public static void main(String[] args) {
// 虚拟机抛出异常
// System.out.println(10 / 0);
int age = 1130;
if (age<0 || age>130) {
// System.out.println("年龄非法");
// 手动抛出异常
throw new RuntimeException("年龄非法");
}
}
}
1.5 异常传递
-
异常是会传递给调用者的
-
按照方法的调用链反向传递
-
如果异常一直没有得到有效的处理,最终传递给JVM,JVM抛出异常并打印信息
- 按照方法调用链反向打印堆栈追踪信息
public class Demo03 {
public static void main(String[] args) {
/**
* main >>> show01 >>> show02 >>> show03
* show03 <<< show02 <<< show01 <<< main
*/
System.out.println("main方法开始...");
show01();
System.out.println("main方法结束...");
}
public static void show01() {
System.out.println("show01方法开始...");
show02();
System.out.println("show01方法结束...");
}
public static void show02() {
System.out.println("show02方法开始...");
show03();
System.out.println("show02方法结束...");
}
public static void show03() {
System.out.println("show03方法开始...");
System.out.println(10/0);
System.out.println("show03方法结束...");
}
}
二、异常处理【重点】
2.1 异常处理语法
try {
可能出现异常的代码
} catch(异常01 e){
处理异常代码块01
} catch(异常02 e){
处理异常代码块02
} catch(异常03 e){
处理异常代码块03
}... {
} finally {
无论是否出现异常都要执行的代码
}
import java.io.IOError;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Demo04 {
public static void main(String[] args) throws IOError {
Scanner sc = new Scanner(System.in);
System.out.println("Hello001");
System.out.println("Hello002");
System.out.println("Hello003");
System.out.println("请输入一个整数:");
try {
int num = sc.nextInt();
System.out.println(10 / num);
} catch(InputMismatchException e) {
// 打印堆栈追踪信息
e.printStackTrace();
} catch (ArithmeticException e) {
// e.printStackTrace();
System.err.println("算术运算异常");
} finally {
System.out.println("必须执行的代码");
}
System.out.println("Hello004");
System.out.println("Hello005");
}
}
2.2 finally
- 无论是否遇到异常都会执行的代码
final、finalize、finally
import java.util.Scanner;
public class Demo06 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Hello001");
System.out.println("Hello002");
System.out.println("Hello003");
System.out.println("请输入一个整数:");
try {
int num = sc.nextInt();
System.out.println(10 / num);
} catch(ArithmeticException e) {
System.err.println("正在处理异常...");
// return;
System.exit(0); // 终止虚拟机
} finally {
System.out.println("必须执行的代码...");
}
System.out.println("Hello004");
System.out.println("Hello005");
}
}
三、自定义异常
3.1 概述
- 官方的异常有时候无法准确表示我们项目中的异常【见名知意】
- 开发者可以模仿JDK中的异常来自定义异常
3.2 流程
- 1)创建一个类继承Exception或者RuntimeException
- 2)调用父类中有参数和无参数的构造方法
- 3)在合适的位置抛出异常
IllegalAgeException
/*
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
/**
* Thrown to indicate that a method has been passed an illegal or
* inappropriate argument.
*
* @author
* @since
*/
public class IllegalAgeException extends RuntimeException {
/**
* Constructs an <code>IllegalArgumentException</code> with no
* detail message.
*/
public IllegalAgeException() {
super();
}
/**
* Constructs an <code>IllegalArgumentException</code> with the
* specified detail message.
*
* @param s the detail message.
*/
public IllegalAgeException(String s) {
super(s);
}
private static final long serialVersionUID = -5365630128856068164L;
}
Student
public class Student {
private String name;
private Integer age;
public Student() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
if (age>0 && age<130) {
this.age = age;
} else {
throw new IllegalAgeException("Illegal age: " + age);
}
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
Demo07
public class Demo07 {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("张三");
stu.setAge(23);
System.out.println(stu);
// 设置非法年龄触发异常
stu.setAge(244);
System.out.println(stu);
}
}