1. 异常概述
1.1 异常概念
异常,就是不正常的意思。指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。
Java处理异常的方式是中断处理。
异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行。
1.2 异常体系
异常的根类是java.lang.Throwable
,其下有两个子类:java.lang.Error
与 java.lang.Exception
,平常所说的异常指 java.lang.Exception
。
- Error:严重错误Error,无法通过处理的错误,只能事先避免。
- Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的。
1.3 异常分类
异常分类:根据在编译时期还是运行时期去检查异常
- 编译时期异常:
checked异常
。必检异常
,必须处理。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)。提醒程序员检查本地信息。 - 运行时期异常:
runtime异常
。免检异常
,不强制要求编写代码捕获或声明异常。在运行时期,检查异常。在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)。代码出错而导致程序出现的问题。一般是由于参数传递错误带来的问题。
1.4 异常的作用
- 作用一:异常用来查询Bug关键参考信息。
- 作用二:异常可以作为方法内部一种特殊的返回值,以便通知调用者底层的执行情况。而不是直接打印在控制台上。
2. 异常的处理方式
异常处理的方式:JVM 默认的处理方式、自己处理和抛出异常
2.1 JVM 默认的处理方式
把异常名称、异常原因及异常出现的位置等信息输出在控制台。
程序停止运行,下面代码不会再执行了。
2.2 自己处理(捕获异常)
目的:当代码遇到异常时,可以让程序继续往下执行。
try{
//编写可能会出现异常的代码
}catch(异常类型 e){
//处理异常的代码
//记录日志/打印异常信息/继续抛出异常
}
int[] arr = {1,2,3,4};
try{
//可能出现异常的代码。
sout(arr[10]);
}catch (ArrayIndexOutOfBoundsException e){
sout("索引越界了");
}
sout("111111111");
}
上述代码第4行处会出现异常:
- 程序会在这里创建一个
ArrayIndexOutOfBoundsException
对象,new ArrayIndexOutOfBoundsException()
。 - 拿着这个对象到catch小括号中对比,看括号中的变量是否可以接受这个对象。
- 如能被接受,就表示该异常被捕获,执行catch里代码。
- 当catch里面所有代码执行完毕,继续执行try...catch体系下其他代码。
关于try...catch的几个问题:
-
如果try中没有遇到问题,怎么执行?
try中全部执行,catch中不会执行。
-
如果try中遇到多个问题,怎么执行?
只会运行下述代码第3行,不会运行第4行。
多个异常,必须写多个catch与之对应。
如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定写在下面 。
int[] arr = {1,2,3,4}; try{ sout(arr[10]);//ArrayIndexOutOfBoundsException sout(2/0);//ArithmeticException }catch (ArrayIndexOutOfBoundsException e){ sout("索引越界了"); } sout("111111111"); } //jdk7 可以处理多个异常 catch (ArrayIndexOutOfBoundsException | ArithmeticException e)
-
如果try中遇到问题没有被捕获,怎么执行?
相当于try...catch代码白写了,交给虚拟机处理,运行停止。
- 如果try中遇到了问题,那么try下面其他代码还会执行吗?
遇到问题下面代码不会执行了,直接跳转到catch。
2.3 抛出异常
throws:写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常。
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
编译时异常:必须写
运行时异常:可以不写
throw: 写在方法内,结束方法,手动抛出异常对象,交给调用者,方法中下面代码不再执行。
public static void main(String[] args) {
int[] arr = null;
int max = 0;
//为了使代码继续向下运行try...catch
try {
max = getMax(arr);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
public static int getMax(int[] arr){
if(arr == null){
throw new NullPointerException();
}
//下面代码不会再执行
int max = arr[0];
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
3. 异常中的常见方法
Throwable类中定义了一些查看方法:
public String getMessage()
:获取异常的描述信息,原因(提示给用户的时候,就提示错误原因)。public String toString()
:获取异常的类型和异常描述信息(不用)。public void printStackTrace()
:打印异常的跟踪栈信息并输出到控制台。仅仅打印信息,不会停止运行。红色字体打印,信息最全。(常用)
注:打印错误的信息,System.err.println(123),红色字体。
4. 自定义异常
目的:提供更灵活、更具体的错误处理机制。
// 业务逻辑异常
public class LoginException extends Exception {
/**
* 空参构造
*/
public LoginException() {
}
/**
*
* @param message 异常信息
*/
public LoginException(String message) {
super(message);
}
}
throw new LoginException( name + "已经存在了");
注:避免过渡设计