目录
一、异常分类
1. 受查异常
2.非受查异常
二、 异常的处理
1.提前处理异常
2. 事后处理异常
三、抛出异常
1. 异常的抛出
2. 异常的捕获
1. throws
2. try-catch
3. finally
一、异常分类
异常(Throwable)是指java程序在执行过程中出现的不正常行为。
我们可将Throwable分为两类:Error和Exception.Error就是我们平时所说的错误,而Exception就是我们最常见的异常,接下来我们举几个代码中常见的例子
1. 空指针异常
public static void main(String[] args) {
int[] array = null;
System.out.println(array[0]);
}
2. 算术异常
public static void main(String[] args) {
System.out.println(10/0);
}
3. 数组越界异常
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6};
System.out.println(array[10]);
}
以上三种均是我们常见的异常种类,而异常具体又分为受查异常和非受查异常。
1. 受查异常
我们在写代码的时候,经常会见到如果代码写错的话,代码底部会标红,标红的部分称为受查异常,受查异常是不能通过编译的,所以无法直接运行
在此处int[ ] array = 0下标红,因为int[]是一个数组类型,不能直接赋值单个数字。在编写代码的时候直接显示出来错误的地方我们称之为受查异常。
2.非受查异常
这是我们在开头提到过的算数异常,我们可以发现虽然这个代码在运行的时候也会报出异常,但是我们在编写代码的时候System.out.println(10/0);这一行并未给我们标红,这说明这是一个非受查异常,在运行的时候编译器才会报错。
二、 异常的处理
在平时的处理异常情况下,我们一般有两种处理异常的办法,一种是提前处理异常,一种是事后处理异常。
1.提前处理异常
下面举一个例子来说明提前处理异常
public static void main(String[] args) {
boolean ret = false;
ret = username();
if(!ret){
处理用户名错误异常();
return;
}
ret = password;
if(!ret){
处理密码错误();
return;
}
}
这种方法会在异常出现的时候直接进行异常处理,处理完一个异常在进行下一个代码段的执行,虽然会保证了代码的安全性,但是效率会下降。
2. 事后处理异常
为了防止出现效率过低问题,我们经常会使用try-catch事后处理异常的办法
public static void main(String[] args) {
try{
输入用户名();
输入密码();
}catch (输入用户名异常){
处理输入用户名异常();
}catch (输入密码异常){
处理输入密码异常();
}
}
在try-catch方法中,我们会先完整的运行try中的代码,将异常统一收集到catch中处理。
三、抛出异常
1. 异常的抛出
我们在程序运行的过程中一般不知道发生了什么异常,为了及时的捕捉到异常,我们可以在异常出现的时候抛出异常。
我们通常使用throw来抛出异常,在检测到异常后,我们使用throw语句。
private String userName = "Admin";
private String password = "123456";
public static void loginInfo(String userName,String password)
throws UserNameException,PassWordException{
if(!userName.equals(userName)){
throw new UserNameException("用户名错误");
}
if(!password.equals(password)){
throw new PassWordException("密码错误");
}
System.out.println("登陆成功");
}
注意事项:
1. throw必须写在方法体内部
2. 抛出的对象必须是Exception 或者 Exception 的子类对象
3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
5. 异常一旦抛出,其后的代码就不会执行
2. 异常的捕获
异常的抛出只是提示程序员发生了异常,而异常的捕获是真正的处理异常。
异常的捕获一般有两种方法:throws和try-catch
1. throws
如果异常的发出者并不想处理异常,那么会使用throws方法将异常抛给此方法的调用者,让此方法的调用者来处理此异常
public static void loginInfo(String userName,String password)
throws UserNameException,PassWordException{
if(!userName.equals(userName)){
throw new UserNameException("用户名错误");
}
if(!password.equals(password)){
throw new PassWordException("密码错误");
}
System.out.println("登陆成功");
}
在上例中,我们将两个可能出现的异常UserNameException和PassWordException抛给了方法的调用者。throws声明的异常必须是Exception 或者 Exception 的子类,如果有多个异常我们需要用,来分割开。
2. try-catch
try-catch在之前的例子中我们已经举过
public static void main(String[] args) {
try{
输入用户名();
输入密码();
}catch (输入用户名异常){
处理输入用户名异常();
}catch (输入密码异常){
处理输入密码异常();
}finally{
return;
}
}
值得注意的是,finally语句是一定会执行的。
我们可以使用try-catch语句来同时抛出多个异常。
catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
...
}
如果抛出的异常具有父子关系,那么一定是子异常在前catch,父异常在后catch,否则会出现语法错误。
3. finally
在写程序的时候我们不能只顾着处理异常,处理异常之后代码还是要继续执行,为了防止代码处理完异常就停下的情况,我们会使用finally语句来继续执行继续往下走的代码。
public static void main(String[] args) {
try{
输入用户名();
输入密码();
}catch (输入用户名异常){
处理输入用户名异常();
}catch (输入密码异常){
处理输入密码异常();
}finally{
接下来的代码;
}
}
finally语句在无论是否发生异常的情况下都会继续执行