定义:
程序在运行过程中遇见的不正常的情况
相关的概念:
java针对程序运行时出现的异常都包装成了异常类,便于程序员调试,也便于编程中统一处理异常
分类:
- 编译时异常、检查时异常、非运行时异常:必须在编程时进行处理,否则无法通过编译,在java文件编译成.calss文件时出现的异常。例:
- IOException
- FileNotFoundException
- ClassNotFoundException
- 运行时异常、非检查性异常、非编译时异常:不必处理,在程序运行时由于虚拟机操作出现的异常,例:
- ArithmeticException
- ArrayIndexOutOfBoundsException
- ClassCastException
异常的体系分支:
Throwable
__|__
| |
Error Exception
__|__
| |
编译时异常 RuntimeException
|
运行时异常
Error和Exception的区别:
- Error的父类是java.lang.Error,Exception的父类是java.lang.Exception
- 错误一般情况下是jvm出现了不正常的情况,会导致程序崩溃,错误无法处理
异常的处理:
- 关键字:try catch finally throw throws
- 处理方式:
- 通过逻辑判断规避异常,需要程序员编写大量的代码去补漏洞,容易遗漏、导致代码很繁杂。
- 使用try…catch…finally…代码块处理异常:try:尝试执行可能有异常的代码、catch:用于捕获可能发生的异常,可以有多个、finally:无论是否发生异常,都会执行。会在return之前执行。遇到System.exit(0);不会执行。
- 注意:1、多个catch捕获的异常,必须从小到大。2、建议try代码块中的代码尽可能少,尽可能小的影响代码的执行效率,也便于定位异常。3、try必须有,catch和finally二选其一。都可以构成代码块。
- 使用throws声明异常:在可能出现异常的方法上声明可能出现的异常类。这个方法的调用者需要做统一处理。
private static void test1() {
int i = 1 / 0; // ArithmeticException
int[] array = new int[2];
array[2] = 1;
File file = new File("d://test.txt");
try {
FileInputStream fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
通过try…catch…处理异常但是过程过于繁琐
private static void test2() {
Scanner input = new Scanner(System.in);
System.out.println("请输入被除数:");
try {
int a = input.nextInt();
System.out.println("请输入除数:");
int b = input.nextInt();
// 1.通过逻辑判断规避异常
// if (b == 0) {
// System.out.println("除数不能为0");
// return; // 结束当前方法
// }
System.out.println(a / b);
} catch(ArithmeticException e) {
System.out.println("除数不能为0");
// return;
// System.exit(0);
} catch(InputMismatchException e) {
System.out.println("必须输入整数");
} catch(Exception e) {
System.out.println("其他异常");
} finally {
System.out.println("finally");
}
System.out.println("end");
}
通过throws声明异常,进行统一处理:
private static void test3() throws ArithmeticException, InputMismatchException {
int a = 0;
int b = 0;
Scanner input = new Scanner(System.in);
System.out.println("请输入被除数:");
a = input.nextInt();
System.out.println("请输入除数:");
b = input.nextInt();
System.out.println(a / b);
System.out.println("end");
input.close();
}
public static void main(String[] args) {
try {
test3();
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
} catch (InputMismatchException e) {
System.out.println("请输入整数");
}
}
自定义异常的使用:
public class AgeOutOfRangeException extends Exception {
private static final long serialVersionUID = 1L;
public AgeOutOfRangeException() {
super();
}
public AgeOutOfRangeException(int age) {
super(age + "不在0~200之间");
}
}
public class NameIsHWZException extends RuntimeException {
private static final long serialVersionUID = 1L;
public NameIsHWZException() {
super("姓名不能是胡维柱");
}
}
public class Student {
private String name;
private int age;
public Student() {
super();
}
/**
* 在需要抛出异常的地方new一个异常对象,然后在用throws把异常声明出来
*/
public Student(String name, int age) throws NameIsHWZException, AgeOutOfRangeException {
super();
if (name.equals("胡维柱")) {
throw new NameIsHWZException();
}
this.name = name;
if (age < 0 || age > 200) {
throw new AgeOutOfRangeException(age);
}
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
/**
* 在实例中要去捕获这些异常
*/
private static void test4() {
Student stu = null;
try {
stu = new Student("胡维柱", 300);
} catch (NameIsHWZException e) {
e.printStackTrace();
} catch (AgeOutOfRangeException e) {
e.printStackTrace();
}
System.out.println(stu);
}
程序员中可以看到的调试的方法:
e.printStackTrace(); // 打印异常栈跟踪信息
System.out.println(e.getMessage()); // 获取异常详细详细