欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > Java——异常

Java——异常

2024/10/24 13:22:51 来源:https://blog.csdn.net/m0_74100417/article/details/140370702  浏览:    关键词:Java——异常

目录

  • 一、什么是异常
  • 二、异常的体系结构
      • 异常分类
  • 三、异常的处理过程
    • 1.异常的抛出
    • 2.异常的捕获
    • 3.throws异常声明
    • 4.try - catch 捕获处理异常
    • 5.finally
    • 6.异常处理流程总结
  • 四、自定义异常

在这里插入图片描述

一、什么是异常

在我们日常生活中,我们可能会生病,会头疼,会肚子疼,打球的时候也可能会受伤。再程序中也是一样,运行时难免会出现一些奇奇怪怪的问题。
在Java中,将程序执行过程中发生的不正常行为称为异常。

例如:
算数异常

        //算数异常System.out.println(10 / 0);Exception in thread "main" java.lang.ArithmeticException: / by zeroat Test.main(Test.java:4)

数组越界异常

//数组越界异常int[] arr = {1,2,3,4};System.out.println(arr[4]);Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4at Test.main(Test.java:8)

空指针异常

//空指针异常String str = null;System.out.println(str.length());Exception in thread "main" java.lang.NullPointerExceptionat Test.main(Test.java:12)

在Java中不同类型的异常,都有与其对应的类来进行描述。

二、异常的体系结构

感觉异常还是挺多的,那在Java中是怎么分类管理的呢?构建一个异常的体系结构。
在这里插入图片描述
从图中可以看到:
Throwable:是顶层类,其有两个子类Error Exception.
Error 是指Java虚拟机无法解决的严重问题,如StackOverflowError栈溢出,OutOfMemoryError堆溢出。
Exception: 程序员可以通过代码进行处理,让程序继续执行。

异常分类

异常可能在编译时发生,叫编译时异常,也叫受检查异常。
如:java.lang.CloneNotSupportedException

public class Dog {public String name;public String age;public Dog clone() {return (Dog) super.clone();}}

在这里插入图片描述
在这里插入图片描述

在运行时发生,叫运行时异常,也叫非受检查异常。
RunTimeException以及其子类对应的异常,都称为运行时异常。
比如:
NullPointerException、
ArrayIndexOutOfBoundsException、ArithmeticException

注意:
编译时出现的语法性错误,不能叫做异常。
在这里插入图片描述
运行时异常时经过编译生成字节码Class文件,再有Java执行过程中出现的错误。

三、异常的处理过程

事前防御型:在操作之前就做充分的检查。代码比较混乱,正常操作与处理错误的操作混合。

//以和平精英为例Boolean login = loginGame();if(login==false) {处理登录失败的错误;return;}login = matchTeammates();if(login==false) {处理匹配队友失败的错误;return;}login = loadingScreen();if(login==false) {处理加载地图失败的错误;return;}...

事后认错型:先操作,遇到问题再处理解决。正常处理流程和错误处理流程分开,代码清晰易理解。

try{loginGame();matchTeammates();loadingScreen();}catch (loginGameException e){处理登录失败的错误;}catch (matchTeammatesException e){处理匹配队友失败的错误;}catch (loadingScreenException e){处理加载地图失败的错误;}....

1.异常的抛出

throw ,抛出一个指定的异常对象,将错误的信息传递给调用者。

throw new xxxException("异常产生的原因")
public class Test {public static void main(String[] args) {int[] arr = {1,2,3,4,5};getArrayElement(arr,1);}public static int getArrayElement(int[] arr,int index) {if(arr==null) {throw new NullPointerException("数组空指针异常");}if(index<0 || index>arr.length-1) {throw new IndexOutOfBoundsException("数组下标越界");}return arr[index];}
}

注意y一下几点:

  • throw必须写在方法体的内部
  • 抛出的对象必须是Exception / Exception 的子类
  • 如果抛出的是运行时异常 RunTimeException / RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
  • 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
  • 异常一旦抛出,其后的代码就不会执行

2.异常的捕获

  • throws异常声明
  • try - catch 捕获处理

3.throws异常声明

用于当前的方法不处理异常,提醒调用者来处理异常。


修饰符 返回值类型 方法名(参数列表)throws 异常类型1,异常类型2 ... {...
}

以上面的小狗类为例子:

public class Dog {public String name;public String age;public Dog clone() throws CloneNotSupportedException{return (Dog) super.clone();} //throws抛给调用者,此时为Test}public class Test {public static void main(String[] args) throws CloneNotSupportedException {Dog dog = new Dog();dog.clone();//此时Test也不处理,抛给JVM来处理。//一旦交给JVM处理,程序就终止了!}
}

注意事项:

  • throws必须出现方法的参数列表后
  • 声明的异常必须是Exception,及其子类,不能是Error
  • 如果需要抛出多个异常,则异常之间用逗号隔开,如果抛出的异常有父子关系,则直接声明父类即可!
  • 使用throws,调用者必须对该异常进行处理,或继续使用throws

4.try - catch 捕获处理异常

由上可知throws并没有对异常进行有效的处理,此时就需要用到try - catch了!

try {//可能会出现异常的代码}catch(异常类型1 e) {// 对try中的代码块出现的异常类型1进行捕获//没出现异常就直接跳过了
}catch(异常类型2 e) {// 对try中的代码块出现的异常类型2进行捕获//没出现异常就直接跳过了
}
    public static void main(String[] args) {int[] arr = {1,2,3,4};System.out.println("异常处理开始-------");try{System.out.println(arr[21]);arr=null;System.out.println(arr.length);}catch (NullPointerException e) {e.printStackTrace();}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();}System.out.println("异常处理结束-------");}

在这里插入图片描述
为啥这个异常信息在最后输出?因为和System.out.println()输出的方式不一样。
注意事项:

  • try里只要哪一行抛出异常,其后面的代码则不再执行
  • 出现的异常会与catch中的异常类型进行一 一匹配,一致则捕获,否则继续往上抛,直到JVM
  • 如果异常之间具有父子关系,子一定要在父前,因为父亲可以接受子类的出现的异常,那么子类就没有了意义。
  • 建议不同的异常,分开写,不必直接写Exception
  • 只会抛出一个异常,不会抛出多个异常。

5.finally

再写程序时,有些特定的代码,无论是否发生异常,都需执行。如 打开的文件资源,组后都需关闭,对资源进行回收。也是因为出现异常,有些代码不能执行到。

try {}catch (异常类型 e) {}finally {//无论发生异常与否,都会执行到。
}

那么既然finally 和 try-catch-finally后的代码都会执行到,那么为啥还要有finally?

返回数据,如果正常输入,则s 无法关闭。

public class Test {public static void main(String[] args) {printFunc();}private static int printFunc() {Scanner s = new Scanner(System.in);try {int a = s.nextInt();return a;}catch (InputMismatchException e) {e.printStackTrace();}s.close();return 0;}}

所以有finally

public class Test {public static void main(String[] args) {printFunc();}private static int printFunc() {Scanner s = new Scanner(System.in);try {int a = s.nextInt();return a;}catch (InputMismatchException e) {e.printStackTrace();}finally {s.close();}return 0;}}

6.异常处理流程总结

  • 程序先执行 try 中的代码
  • 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
  • 如果找到匹配的异常类型, 就会执行 catch 中的代码
  • 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
  • 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
  • 如果上层调用者也没有处理的了异常, 就继续向上传递.
  • 一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止

四、自定义异常

虽然Java中异常类有许多了,但是并不能完全表示实际开发中所遇到的一些异常,此时就需要我们自己定义一些异常了。

  • 自定义异常通常会继承Exception(默认为受检查的异常)或RuntimeException(为非受检查的异常)

实现一个用户登录功能,登录用户名或密码错误采用自定义异常类处理。

public class Test {public static void main(String[] args) {try {login("zxh","123456");} catch (UserNameException e) {throw new RuntimeException(e);} catch (PasswordException e) {throw new RuntimeException(e);}}public static void login(String name, String pwd) throws PasswordException, UserNameException {if(!name.equals("zxh")) {throw new UserNameException("用户名错误!");}if(!pwd.equals("123456")) {throw new PasswordException("密码错误!");}System.out.println("登录成功");}
}
public class PasswordException extends Exception{//因为写了hrow new PasswordException("密码错误!"); 传递了参数。public PasswordException(String message) {super(message);}
}
public class UserNameException extends Exception{
//传递了参数public UserNameException(String message) {super(message);}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com