处理异常不再困难-try-catch-finally和throw语句详解

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在软件开发过程中,代码经常会出现各种问题,例如空指针、数组越界等等。在这些情况下,如果不进行处理,程序就会崩溃,严重影响用户体验。而处理这些异常是开发者必须要掌握的技能之一。

  Java中提供了try-catch-finally和throw语句来处理异常。本文将详细介绍这些语句的使用方法,并通过实际案例演示其应用场景及优缺点分析。

摘要

本文主要涉及以下几个方面:

  1. try-catch-finally和throw语句的基本语法和使用方法。

  2. 源代码解析,通过实例演示其应用场景。

  3. 对try-catch-finally和throw语句的优缺点进行分析。

  4. 类代码方法介绍。

  5. 测试用例(以main函数写法为准)。

正文

简介

  Java中的异常分为两种类型:受检异常(checked exception)和非受检异常(unchecked exception)。其中,受检异常是在编译时就能检测到的异常,必须要进行处理。而非受检异常是在运行时才能检测到的异常,可以进行处理也可以不进行处理。

  Java中使用try-catch-finally和throw语句来处理异常。其中,try-catch-finally语句用于捕获异常并进行处理,而throw语句用于抛出异常。下面将详细介绍这些语句的使用方法。

源代码解析

try-catch-finally语句

  try-catch-finally语句用于捕获异常并进行处理。其基本语法如下:

try {
    // 可能会抛出异常的代码块
} catch (异常类型1 异常变量1) {
    // 异常处理代码1
} catch (异常类型2 异常变量2) {
    // 异常处理代码2
} finally {
    // 无论是否抛出异常,都会执行的代码块
}

  在try语句块中,开发者可以编写可能会抛出异常的代码。如果在try语句块中抛出了异常,程序会跳转到相应的catch语句块进行异常处理。如果没有抛出异常,程序会跳过catch语句块,直接执行finally语句块。

  catch语句块可以有多个,并且需要按照从上到下的顺序进行排列。如果抛出的异常类型与catch语句块中的异常类型匹配,则会执行对应的catch语句块进行异常处理。如果抛出的异常类型与所有catch语句块中的异常类型均不匹配,则会向上抛出异常。

  finally语句块中的代码无论是否抛出异常,都会被执行。通常将一些必须要执行的代码放在finally语句块中,例如关闭文件、关闭网络连接等等。

  下面通过实例演示try-catch-finally语句的应用场景。

public class MyFileUtils {
    public static void copyFile(String src, String dest) {
        FileInputStream input = null;
        FileOutputStream output = null;
        try {
            input = new FileInputStream(src);
            output = new FileOutputStream(dest);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = input.read(buffer)) != -1) {
                output.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  在上面的代码中,我们封装了一个copyFile方法,用于将源文件复制到目标文件中。在方法中,我们使用了try-catch-finally语句来进行异常处理。

  在try语句块中,我们打开了源文件和目标文件,并使用一个byte数组来进行文件的读写操作。在catch语句块中,我们对抛出的IOException异常进行了简单的处理,并打印了异常堆栈信息。在finally语句块中,我们关闭了文件流,以确保资源被正确释放。

  根据如上代码分析可得:
  该代码定义了一个 MyFileUtils 类,其中包含了一个用于复制文件的静态方法 copyFile。该方法接收两个字符串参数:源文件路径 src 和目标文件路径 dest

  在方法中,首先创建了两个文件流对象 inputoutput,用于读取和写入文件。然后使用 FileInputStreamFileOutputStream 类传入对应的文件路径来初始化这两个流对象。

  接下来,使用一个 byte 类型的数组作为缓冲区,以便分段读取源文件的内容。在 while 循环中,每次从输入流中读取一定数量的数据到缓冲区中,然后将缓冲区中的数据写入到输出流中。

  最后在 finally 块中对输入流和输出流进行关闭操作,以释放资源。

  值得注意的是,在方法中使用了 try-catch 块捕获了 IOException 异常,在出现异常时会打印异常信息,但并不会对异常进行处理。如果在使用该方法时出现异常,需要根据具体情况进行处理。

throw语句

  throw语句用于抛出异常。其基本语法如下:

throw 异常对象;

  在使用throw语句时,需要先定义一个异常类,例如:

package com.example.javase.se.controlProgram;

/**
 * @Author ms
 * @Date 2023-11-13 23:03
 */
public class MyException extends Throwable {

    public MyException(String message) {
        super(message);
    }

}

  在上面的代码中,我们定义了一个MyException类,它继承自Exception类,并提供了一个带有字符串参数的构造函数。

  根据如上代码分析可得:
  这是一个自定义异常类MyException,它继承自Throwable类,用于创建特定的异常。通过传入异常信息的构造方法来创建MyException实例。在程序运行时,当需要抛出MyException时,可以通过throw new MyException(“异常信息”)语句来抛出。在处理异常时,可以使用try-catch语句捕获并处理MyException异常。

  下面通过实例演示throw语句的应用场景。

public void divide(int a, int b) throws MyException {
    if (b == 0) {
        throw new MyException("除数不能为0");
    } else {
        System.out.println(a / b);
    }
}

  在上面的代码中,我们定义了一个divide方法,用于进行除法运算。如果除数为0,则会抛出一个MyException异常。否则,方法会计算出商并进行输出。

  在上面的代码中,我们使用了throws关键字来声明方法可能会抛出MyException异常。这是因为MyException是一种受检异常,在使用时必须进行处理。

  根据如上代码分析可得:
  该方法用于进行两个整数的除法运算,其中a为被除数,b为除数。在执行除法运算之前,代码进行了一个判断,当除数为0时,抛出自定义异常MyException,异常信息为“除数不能为0”。如果除数不为0,则执行除法运算并输出结果。如果在执行过程中抛出了MyException异常,该异常会被抛到方法的调用处,由调用方来处理该异常。

应用场景案例

  在Java中,try-catch-finally和throw语句的应用场景非常广泛。下面将通过实际案例演示它们的应用场景。

文件操作

  在Java中,进行文件操作时经常会出现I/O异常,例如文件不存在、文件读写错误等等。此时,我们通常会使用try-catch-finally语句来进行异常处理。下面是一个例子。

public class MyFileUtils {
    public static void copyFile(String src, String dest) {
        FileInputStream input = null;
        FileOutputStream output = null;
        try {
            input = new FileInputStream(src);
            output = new FileOutputStream(dest);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = input.read(buffer)) != -1) {
                output.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  在上面的代码中,我们封装了一个copyFile方法,用于将源文件复制到目标文件中。在方法中,我们使用了try-catch-finally语句来进行异常处理。

  在try语句块中,我们打开了源文件和目标文件,并使用一个byte数组来进行文件的读写操作。在catch语句块中,我们对抛出的IOException异常进行了简单的处理,并打印了异常堆栈信息。在finally语句块中,我们关闭了文件流,以确保资源被正确释放。

  根据如上代码分析可得:
  这是一个 Java 类,名为 MyFileUtils。

  其中有一个静态方法 copyFile,该方法接受两个字符串参数,分别为源文件路径和目标文件路径。该方法的作用是将源文件复制到目标文件。

  在该方法中,使用了 FileInputStream 和 FileOutputStream 对象来读写文件。使用了一个 byte 数组作为缓存区,每次从 FileInputStream 中读取数据到缓存区,再将缓存区的数据写入 FileOutputStream。

  在 try-catch 块中处理了可能出现的 IOException 异常。在 finally 块中关闭了 FileInputStream 和 FileOutputStream 对象,确保资源释放。

数组操作

  在Java中,进行数组操作时经常会出现数组越界异常,例如访问不存在的数组下标等等。此时,我们通常会使用try-catch语句块来进行异常处理。下面是一个例子。

public class MyArrayUtils {
    public static int getElement(int[] array, int index) {
        try {
            return array[index];
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            return -1;
        }
    }
}

  该代码演示了try-catch-finally语句的一个典型应用场景:文件操作。在该例子中,我们封装了一个copyFile方法用于将源文件复制到目标文件。在try语句块中,我们打开了源文件和目标文件,并使用一个byte数组来进行文件的读写操作。如果在读写过程中出现IOException异常,就会跳转到catch语句块中进行异常处理。在catch语句块中,我们对抛出的异常进行了简单的处理,并打印了异常堆栈信息。在finally语句块中,我们关闭了文件流,以确保资源被正确释放。

  此外,还演示了另一个典型应用场景:数组操作。在该例子中,我们封装了一个getElement方法用于获取数组中指定下标的元素。我们使用了try-catch语句块来进行异常处理。如果访问的下标越界,就会跳转到catch语句块中进行异常处理。在catch语句块中,我们对抛出的异常进行了简单的处理,并打印了异常堆栈信息,同时返回-1作为方法的返回值。

  总的来说,try-catch-finally和throw语句在Java中的应用场景非常广泛,可以用于处理各种异常情况,保证程序的正确性和稳定性。

优缺点分析

try-catch-finally语句的优缺点

优点
  1. 适用范围广:try-catch-finally语句可以用于处理各种受检、非受检异常,在Java中应用广泛。
  2. 减少程序崩溃率:通过try-catch-finally语句,可以对抛出的异常进行有效处理,从而避免程序崩溃。
  3. 确保资源被释放:在finally语句块中,可以确保程序执行完后关闭资源,避免资源泄露问题。
缺点
  1. 程序可读性降低:过多的try-catch语句会让程序变得更加冗长,可读性降低。
  2. 可能会掩盖错误:如果catch语句块中的异常处理不当,可能会掩盖真正的错误,导致后续程序出现问题。

throw语句的优缺点

优点
  1. 可以抛出自定义异常:通过throw语句,开发者可以自定义异常类,并进行抛出。
  2. 规范异常处理:通过抛出异常,开发者可以引导程序执行指定的异常处理方法,避免程序崩溃。
缺点
  1. 只能抛出一个异常:throw语句只能抛出一个异常,如果需要抛出多个异常,则需要添加多个throw语句。
  2. 异常处理不当会影响程序性能:如果throw语句使用不当,可能会导致程序性能下降。

类代码方法介绍

try-catch-finally语句

try {
    // 可能会抛出异常的代码块
} catch (异常类型1 异常变量1) {
    // 异常处理代码1
} catch (异常类型2 异常变量2) {
    // 异常处理代码2
} finally {
    // 无论是否抛出异常,都会执行的代码块
}

  在try语句块中,开发者可以编写可能会抛出异常的代码。如果在try语句块中抛出了异常,程序会跳转到相应的catch语句块进行异常处理。如果没有抛出异常,程序会跳过catch语句块,直接执行finally语句块。

  catch语句块可以有多个,并且需要按照从上到下的顺序进行排列。如果抛出的异常类型与catch语句块中的异常类型匹配,则会执行对应的catch语句块进行异常处理。如果抛出的异常类型与所有catch语句块中的异常类型均不匹配,则会向上抛出异常。

  finally语句块中的代码无论是否抛出异常,都会被执行。通常将一些必须要执行的代码放在finally语句块中,例如关闭文件、关闭网络连接等等。

throw语句

throw 异常对象;

  在使用throw语句时,需要先定义一个异常类。在抛出异常时,需要将异常对象作为参数传递给throw语句。当程序执行到throw语句时,会将异常对象抛出,进入异常处理过程。

测试用例

下面提供一些测试用例,供读者参考。

try-catch-finally语句

try {
    int a = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("除数不能为0");
} finally {
    System.out.println("程序执行完毕");
}

  在上面的代码中,我们使用了try-catch-finally语句来进行异常处理。在try语句块中,我们进行了一个除法运算,但是除数为0,会抛出ArithmeticException异常。在catch语句块中,我们对抛出的异常进行了处理。在finally语句块中,我们打印了一条语句,表示程序执行完毕。

throw语句

public static void printName(String name) throws MyException {
    if (name == null || name.isEmpty()) {
        throw new MyException("姓名不能为空");
    } else {
        System.out.println("姓名为:" + name);
    }
}

  在上面的代码中,我们定义了一个printName方法,用于打印姓名。在方法中,我们使用了throw语句来抛出一个MyException异常。如果传入的姓名为null或者空字符串,就会抛出该异常。如果传入的姓名不为空,就会打印该姓名。在方法签名中,我们使用throws关键字声明方法可能会抛出MyException异常。

  根据如上代码测试结果如下:

在这里插入图片描述
  根据如上代码分析可得:
  这是一个静态方法,方法名为printName,参数为一个String类型的name。方法中先判断传入的name是否为null或者空字符串,如果是,则抛出一个自定义的异常MyException,异常信息为“姓名不能为空”。如果name不为null且不为空,则输出“姓名为:”加上name的值。同时,这个方法声明了一个抛出MyException异常,表示调用该方法的代码可能会遇到这个异常,需要进行异常处理。

总结

  本文深入介绍了Java中异常处理相关的知识,主要包括try-catch-finally语句和throw语句的基本语法和使用方法。同时,通过实例演示和优缺点分析,阐述了它们的应用场景和优缺点。

  try-catch-finally语句作为Java中必不可少的异常处理语句,可以用于处理各种受检、非受检异常,在Java中应用广泛。通过try-catch-finally语句,可以对抛出的异常进行有效处理,从而避免程序崩溃。同时,在finally语句块中,可以确保程序执行完后关闭资源,避免资源泄露问题。但是,过多的try-catch语句会让程序变得更加冗长,可读性降低,如果catch语句块中的异常处理不当,可能会掩盖真正的错误,导致后续程序出现问题。

  throw语句可以用于抛出自定义异常,并引导程序执行指定的异常处理方法,避免程序崩溃。它的缺点是只能抛出一个异常,如果需要抛出多个异常,则需要添加多个throw语句。如果throw语句使用不当,可能会导致程序性能下降。

  最后,本文提供了一些测试用例供读者参考,希望能够对读者理解和掌握Java异常处理相关知识有所帮助。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值