目录
一、异常概述
在Java中,将程序执行过程中发生的不正常行为称为异常。
java中不同类型的异常,都有与其对应的类来进行描述。
二、异常的体系结构
异常可能在编译时发生,也可能在程序运行时发生,根据发生的时机不同,可以将异常分为:
1.Runtime Exception(运行时异常):
如IndexOutOfBoundsException(数组越界异常)、NullPointerException(空指针异常)等;
运行时异常:在程序执行期间发生的异常,称为运行时异常,也称为非受检查异常(Unchecked Exception);
运行时异常RunTimeException以及其子类对应的异常,都称为运行时异常。
运行时异常指的是程序已经编译通过得到class 文件了, 再由 JVM 执行过程中出现的错误;
2.其他异常(编译时异常):
如FileNotFoundException、EOFException等;
编译时异常:在程序编译期间发生的异常,称为编译时异常,也称为受检查异常(Checked Exception);编译时异常在编译阶段产生,必须手动处理,否则代码报错;
编译时出现的语法性错误,不能称之为异常(啥啥就异常了,那只是你写错了。异常的是你,不是我,代码们如是说到)。
在编译阶段,Java不会运行代码,只会检查语法是否错误,或者性能优化,编译时异常更多是为了提醒程序员检查本地信息;
三、异常的作用
1.异常常用于查询Bug的关键参考信息;
2.异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况;
四、异常的处理方式
异常的具体处理方式,也称为异常的捕获,主要有以下几种:
1.JVM默认处理方式
把异常名称,异常原因及异常出现的位置等信息在控制台输出;
程序停止执行;
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(arr[4]);
System.out.println("abc"); //没有打印;
}
//运行后报异常,数组越界异常;
/*打印的内容:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at ProjectMain.Main.main(Main.java:16)
*/
//字符串"abc"没有被打印;
2.异常捕获 try-catch
当代码出现异常时,可以让程序继续往下执行。
public static void main(String[] args) {
int[] arr = {1,2,3};
try{
System.out.println(arr[4]);
}catch (ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
System.out.println("abc"); //该行代码有打印;
}
//运行后报异常,数组越界异常;
/*打印的内容:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at ProjectMain.Main.main(Main.java:16)
abc
*/
//字符串"abc"成功被打印,证明异常被捕获,捕获后程序继续执行;
3.异常抛出处理throws throw
throws写在方法定义处,表示声明一个异常,用于告诉调用者,使用本方法可能会有哪些异常;
throw写在方法内,结束方法。手动抛出异常对象,交给调用者,方法中抛出异常代码下方的代码不再执行;
public class Main {
public static int getElement(int[] array, int index){
if(null == array){
throw new NullPointerException("传递的数组为null");
}
System.out.println("数组不为空"); //有输出;
if(index < 0 || index >= array.length){
throw new ArrayIndexOutOfBoundsException("传递的数组下标越界"); //抛出异常,后续代码不再执行;
}
return array[index];
}
public static void main(String[] args) throws ArrayIndexOutOfBoundsException,NullPointerException{ //声明了可能出现的异常,但是没有处理异常的功能;
int[] array = {1,2,3};
System.out.println(getElement(array, 3)); //没有输出;
}
}
五、异常的处理流程
1.程序先执行 try 中的代码,如果 try 中的代码出现异常,就会结束 try 中的代码,对比和 catch 中的异常类型,确认是否匹配。
2.如果找到匹配的异常类型,就会执行 catch 中的代码,如果没有找到匹配的异常类型,就会将异常向上传递到上层调用者。
3.无论是否找到匹配的异常类型,finally 中的代码都会被执行(在该方法结束之前执行)。
4.如果上层调用者也没有处理的了异常,就继续向上传递,直到 main 方法也没有合适的代码处理异常,就会交给 JVM 来进行处理,此时程序就会异常终止。
六、自定义异常类
Java 中虽然已经内置了丰富的异常类,但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合实际情况的异常结构。
自定义异常可以基于已有的异常类进行扩展(继承),创建新的,和业务相关的异常类,通常会继承自 Exception 或者 RuntimeException;
public class Main {
//用户名和密码;
private static String userName = "admin";
private static String password = "123456";
//声明异常,并在符合条件时抛出异常,但异常并未在该方法内部处理,因此异常被扩散至调用者;
public static void loginInfo(String userName, String password) throws UserNameException,PasswordException{
//根据条件确定是否抛出异常;
if (!userName.equals(Main.userName)) {
throw new UserNameException("用户名错误!");
}
if (!password.equals(Main.password)) {
throw new PasswordException("密码错误!");
}
//如果抛出异常,则不会执行以下代码;
System.out.println("登陆成功");
}
//处理
public static void main(String[] args) {
try {
loginInfo("admin", "23456"); //输入用户名和密码;
} catch (UserNameException e) { //尝试捕获异常;
e.printStackTrace();
} catch (PasswordException e) { //尝试捕获异常;
e.printStackTrace();
}
}
}
//以下定义两个异常类;
class UserNameException extends Exception {
public UserNameException(String message) {
super(message);
}
}
class PasswordException extends Exception {
public PasswordException(String message) {
super(message);
}
}
以上代码最终报异常,并打印异常信息:
ProjectMain.PasswordException: 密码错误!
at ProjectMain.Main.loginInfo(Main.java:24)
at ProjectMain.Main.main(Main.java:32)//成功使用了自定义异常;
( 哈哈哈~~ 文章结束!)
( 看到这里,如果有为各位帅哥美女提供一点点灵感,请点一个小小的赞哦,比心💖💖💖 )