异常分类:
Throwable是所有异常和错误的根类
- Error:编译异常或会导致程序中断的错误
- Exception:所有异常类的根类
- 1.RuntimeException:运行时异常,在程序的运行时期可能发生的异常
- 2.CheckedException:必须被处理的异常,在编译器会显示报错,只有try处理后才不会报错
常见异常:
ArithmeticException:算术异常
ArrayIndexOutOfBoundsException:数组越界异常
IndexOutOfBoundsException:下标越界异常
NullPointerException:空指针异常
InputMismatchException:输入不匹配异常
ClassCastException:类型转换异常
必须被处理的异常:
IOException:输入输出异常
SOLException:数据库异常
ClassNotFoundException:类型未找到异常
三种异常处理的情况:
1、程序未发生异常,try块会走完,不会进入catch块,进入finally块,同时继续向下运行
2、程序发生异常并被捕获,try块会走到发生异常的位置后进入catch块,执行完后进入finally块,同时继续向下运行
3、程序发生异常但未被捕获,try走到发生异常的位置后进入catch块,进入finally块,不会继续向下运行
处理异常的结构
try-catch结构
try-finally结构(很少用)
try-catch-finally结构
try-catch
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
int a = sc.nextInt();
int b = sc.nextInt();
System.out.println(a+"/"+ b +"="+ a/ b);
}catch (ArithmeticException e){
//打印堆栈信息
// e.printStackTrace();
System.out.println(e.getMessage());
System.err.println(e.getMessage());
System.out.println("分母为0,不合法");
}catch (InputMismatchException e){
System.out.println("输入类型不匹配");
}
System.out.println("感谢使用本程序!");
try {
//必须被处理的异常
Class.forName("");
}catch (ClassNotFoundException e){
}
}
try-catch-finally
public static void main(String[] args) {
//ArrayIndexOutOfBoundsException 数组越界异常
// int[] a={};
// System.out.println(a[0]);
//NullPointerException 空指针异常
String s = null;
try {
ng str = s.toString();
}
//catch和finally至少用一个,finally无论是否发生异常,是否捕获,都会运行
catch (ArithmeticException e) {
e.printStackTrace();
}finally {
System.out.println("最终块代码");
}
}
e.printStackTrace();打印出错堆栈的信息
catch块会捕获时同时新开堆栈继续运行
所以会发生打印堆栈信息和其他打印信息顺序不正常
e.getMessage();返回的是异常类型后的具体异常信息
有return的finally块
无返回值:catch中如果有return,会在finally块运行完在运行catch的return
有返回值:catch块的return会正常运行,finally块运行完会再回到catch的return处,但不会再次运行,如果finally中也有return,则会覆盖catch的return
public void test(){
try {
int a = 1/0;
}catch (Exception e){
System.out.println("进入catch块");
return;
}finally {
System.out.println("进入finally块");
}
}
public int testA(){
int i = 1;
try {
int a = 1/0;
i++;//执行不到
}catch (Exception e){
System.out.println("进入catch块");
i++;//i=2
//return在i=2时执行过一次,return只执行一次,当finally结束后i=3不会被return
return i;
}finally {
System.out.println("进入finally块");
i++;//i=3
return i;
}
}
public static void main(String[] args) {
Demo3 d = new Demo3();
d.test();
System.out.println(d.testA());
}
如果finally有return,i=3;如果没有,i=2
排列catch 语句的顺序:
先子类后父类
发生异常时按顺序逐个匹配
只执行第一个与异常类型匹配的catch语句
自定义异常
//extends是决定自定义异常的分类
public class WrongAgeException extends RuntimeException {
public WrongAgeException(String message) {
super(message);
}
}
class User{
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>100||age<0){
throw new WrongAgeException("输入年龄错误");
}
this.age = age;
}
public static void main(String[] args) {
User u = new User();
try {
u.setAge(80);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(u.getAge());
}
}