面试之异常处理,自定义异常,finally执行规则

导读:本篇文章讲解 面试之异常处理,自定义异常,finally执行规则,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、Java异常类层次结构

img

在 Java 中,所有的异常都有一个共同的祖先 java.lang 包中的 Throwable 类。Throwable 类有两个重要的子类:

  • Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。Exception 又可以分为 Checked Exception (受检查异常,必须处理) 和 Unchecked Exception (不受检查异常,可以不处理)。
  • ErrorError 属于程序无法处理的错误 ,我们没办法通过 catch 来进行捕获 。例如Java 虚拟机运行错误(Virtual MachineError)、虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等 。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。

Checked Exception 和 Unchecked Exception 有什么区别?

Checked Exception 即受检查异常,Java 代码在编译过程中,如果受检查异常没有被 catch/throw捕获 或者throw往外抛处理的话,就没办法通过编译 。

除了RuntimeException及其子类以外,其他的Exception类及其子类都属于受检查异常 。常见的受检查异常有: IO 相关的异常、ClassNotFoundExceptionSQLException…。

Unchecked Exception不受检查异常 ,Java 代码在编译过程中 ,我们即使不处理不受检查异常也可以正常通过编译。

RuntimeException 及其子类都统称为非受检查异常,例如:NullPointerExceptionNumberFormatException(字符串转换为数字)、ArrayIndexOutOfBoundsException(数组越界)、ClassCastException(类型转换错误)、ArithmeticException(算术错误)等。

二、Throwable类常用方法

  • public String getMessage(): 返回异常发生时的简要描述
  • public String toString(): 返回异常发生时的详细信息
  • public String getLocalizedMessage():返回异常对象的本地化信息。使用Throwable的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与 getMessage()返回的结果相同
  • public void printStackTrace():在控制台上打印 Throwable 对象封装的异常信息

三、try-catch-finally

  • try块: 用于捕获异常。其后可接零个或多个catch 块,如果没有 catch块,则必须跟一个 finally 块。

  • catch块: 用于处理 try 捕获到的异常。

  • finally块: 无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try块或 catch块中遇到return语句时,finally 语句块将在方法返回之前被执行。

    注意:不要在 finally 语句块中使用 return! 当 try 语句和 finally 语句中都有 return 语句时,try 语句块中的 return 语句不会被执行。

    public static void main(String[] args) {
        System.out.println(f(2));;
    }
    
    public static int f(int value) {
        try {
            return ++value;
        } finally {
            if (value == 2) {
                return 0;
            }
        }
    }
    

    输出:

    0
    

finally 中的代码一定会执行吗?

在以下 2种特殊情况下,finally 块不会被执行:

  1. tryfinally块中用了 System.exit(int)退出程序。但是,如果 System.exit(int) 在异常语句之后,finally 还是会被执行
  2. 程序所在的线程死亡。

代码示例:

try {
    System.out.println("Try to do something");
    throw new RuntimeException("RuntimeException");
} catch (Exception e) {
    System.out.println("Catch Exception -> " + e.getMessage());
    // 终止当前正在运行的Java虚拟机
    System.exit(1);
} finally {
    System.out.println("Finally");
}

四、使用 try-with-resources 来代替try-catch-finally(⭐️ ⭐️ ⭐️ )

  1. 适用范围(资源的定义): 任何实现 java.lang.AutoCloseable 的对象

  2. 关闭资源和 finally 块的执行顺序:try-with-resources 语句中,任何 catch 或 finally 块在声明的资源关闭后运行

    《Effecitve Java》中明确指出:

    面对必须要关闭的资源,我们总是应该优先使用 try-with-resources 而不是try-finally。随之产生的代码更简短,更清晰,产生的异常对我们也更有用。try-with-resources语句让我们更容易编写必须要关闭的资源的代码,若采用try-finally则几乎做不到这点。

    ​ 代码示例:

    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader("test.txt"));
        br.readLine();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (br != null)
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
    

    ​ 将上面的代码例子改造:

    try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
        br.readLine();
    } catch (Exception e) {
        e.printStackTrace();
    }
    

    ​ 代码变得非常简洁。

    注意:try-with-resource中声明的变量会隐式的加上final 关键字,所以无法再进行赋值。

五、自定义异常

​ 在Java中要想创建自定义异常,需要继承Throwable或者他的子类Exception。

因为父类已经把异常信息的操作都完成了,所在子类只要在构造时,将异常信息传递给父类通过super 语句即可。

代码示例:

public class CustomException extends Exception {

	//无参构造方法
	public CustomException(){
		
		super();
	}
	
	//有参的构造方法
	public CustomException(String message){
		super(message);
		
	}
	
	// 用指定的详细信息和原因构造一个新的异常
	public CustomException(String message, Throwable cause){
		
		super(message,cause);
	}
	
	//用指定原因构造一个新的异常
	 public CustomException(Throwable cause) {
		 
		 super(cause);
	 }
	
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/68416.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!