异常处理
一、异常体系
java中通过类对所有的不正常的现象进行描述,并封装为对象。由这些类组成的一个专门处理Java中的各种异常的体系称为Java的异常体系。
java的异常体系包含在java.lang这个包默认不需要导入。
java异常体系
Throwable | Error (错误) | |
Exceprion (异常) | RuntimeException (运行时异常) | |
IOException(非运行时异常) |
找来的异常体系图
如何判断一个错误与异常:
如果程序出现了不正常的信息,如果不正常的信息的类名是以Error结尾的,那么肯定是一个错误。
如果是以Exception结尾的,那么肯定就是一个异常。
二、Throwable类的几种常用方法
- toString() 输出该异常的类名。
- getMessage() 输出异常的信息,需要通过构造方法传入异常信息(例如病态信息)。
- printStackTrace() 打印栈信息。
public class Main {
public static void main(String[] args)
{
//创建了一个Throwable对象。
Throwable t = new Throwable("this is a throwable");
String info = t.toString();
String message = t.getMessage();
System.out.println("toString: "+ info); // java.lang.Throwable 包名+类名 = 完整类名
System.out.println("message: "+ message);
test();
}
public static void test(){
//
Throwable t = new Throwable();
t.printStackTrace();
}
}
三、异常的两种处理方式
方式一:捕获处理
1.捕获处理的格式
try{
可能发生异常的代码
}catch(捕获的异常类型 变量名){
处理异常的代码
}
public class Main {
public static void main(String[] args)
{
int[] arr = null;
div(4,0,arr);
}
public static void div(int a , int b,int[] arr){
int c = 0;
try{
c = a/b; //jvm在这句话的时候发现了不正常的情况,那么就会创建一个对应的异常对象,跳转至catch部分
System.out.println("数组的长度:"+ arr.length);//该异常不会被捕获到
}catch(ArithmeticException e){
System.out.println("出现了算术异常!");
System.out.println("toString:"+ e.toString());
}catch(NullPointerException e){
System.out.println("出现了空指针异常!");
System.out.println("toString:"+ e.toString());
}catch(Exception e){
System.out.println("出现了未知异常!");
}
System.out.println("c="+c);
}
}
2.捕获处理要注意的细节:
- 如果一个try块中出现了异常的代码,经过处理之后,那么try-catch块外面的代码可以正常执行。
- 如果一个try块中出现了异常的代码,那么在try块中出现异常的代码后面 的语句无法执行。
- 一个try块后面可以跟多个catch块,也就是一个try块可以捕获多种异常的类型,但是捕获的异常类型必须从小到大进行捕获。
//如将上例打代码改写为如下,将无法通过编译
try{
c = a/b;
System.out.println("数组的长度:"+ arr.length);
}catch(Exception e){
System.out.println("出现了未知异常!");
}catch(ArithmeticException e){//Exception 'java.lang.ArithmeticException' has already been caught
System.out.println("出现了算术异常!");
System.out.println("toString:"+ e.toString());
}catch(NullPointerException e){//Exception 'java.lang.NullPointerException' has already been caught
System.out.println("出现了空指针异常!");
System.out.println("toString:"+ e.toString());
}
方式二:抛出处理(throw throws)
1.抛出处理的格式
try{
fun()//可能发生异常的代码
}catch(捕获的异常类型 变量名){
处理异常的代码
}
......
fun()throws 抛出的异常类型{
if(异常发生){
throw new 异常类型();
}
}
public class Main {
public static void main(String[] args)
{
try{
int[] arr = null;
div(4,0,arr); //调用了一个 声明抛出异常类型 的方法
}catch(Exception e){ //这里使用了多态
System.out.println("出现异常了...");
e.printStackTrace();
}
}
public static void div(int a, int b,int[] arr) throws Exception {
if(b==0){
throw new ArithmeticException(); //抛出一个异常对象...
}else if(arr==null){
throw new NullPointerException();
}
int c = a/b;
System.out.println("c="+c);
}
}
2.抛出处理要注意的细节:
- 如果一个方法内部抛出了一个编译时异常对象,那么该方法必须要声明抛出。
- 如果调用了一个声明抛出编译时异常的方法,那么调用者必须要处理。
- 如果一个方法抛出了一个异常对象,那么该方法也会马上停止(一个方法遇到了throw关键字,那么该方法就会马上停止)
- 在一种情况下只能抛出一种异常对象。
注意:throw 关键字是用于方法体之内抛出异常对象的,throws是用于方法声明上,声明抛出异常类型的。