Java异常

tim-qtp2025年2月9日...大约 3 分钟Java基础

有哪些异常:

Throwable 是 Java 语言中所有错误和异常的基类。它有两个主要的子类:Error 和 Exception

Error 类代表那些严重的错误,这类错误通常是程序无法处理的。比如,OutOfMemoryError 表示内存不足,StackOverflowError 表示栈溢出。这些错误通常与 JVM 的运行状态有关,一旦发生,应用程序通常无法恢复。

Exception 类代表程序可以处理的异常。它分为两大类:编译时异常(Checked Exception)和运行时异常(Runtime Exception)。

①、编译时异常(Checked Exception):这类异常在编译时必须被显式处理(捕获或声明抛出)。

如果方法可能抛出某种编译时异常,但没有捕获它(try-catch)或没有在方法声明中用 throws 子句声明它,那么编译将不会通过。例如:IOException、SQLException 等。

②、运行时异常(Runtime Exception):这类异常在运行时抛出,它们都是 RuntimeException 的子类。对于运行时异常,Java 编译器不要求必须处理它们(即不需要捕获也不需要声明抛出)。

运行时异常通常是由程序逻辑错误导致的,如 NullPointerException、IndexOutOfBoundsException 等。

异常的处理方式?

①、遇到异常时可以不处理,直接通过throw 和 throws 抛出异常,交给上层调用者处理。

throws 关键字用于声明可能会抛出的异常,而 throw 关键字用于抛出异常。

public void test() throws Exception {
    throw new Exception("抛出异常");
}

②、使用 try-catch 捕获异常,处理异常。

try {
    //包含可能会出现异常的代码以及声明异常的方法
}catch(Exception e) {
    //捕获异常并进行处理
}finally {
    //可选,必执行的代码
}

三道经典异常处理代码题

题目 1

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test());
    }
    public static int test() {
        try {
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            System.out.print("3");
        }
    }
}

test()方法中,首先有一个try块,接着是一个catch块(用于捕获异常),最后是一个finally块(无论是否捕获到异常,finally块总会执行)。

①、try块中包含一条return 1;语句。正常情况下,如果try块中的代码能够顺利执行,那么方法将返回数字1。在这个例子中,try块中没有任何可能抛出异常的操作,因此它会正常执行完毕,并准备返回1

②、由于try块中没有异常发生,所以catch块中的代码不会执行。

③、无论前面的代码是否发生异常,finally块总是会执行。在这个例子中,finally块包含一条System.out.print("3");语句,意味着在方法结束前,会在控制台打印出3

当执行main方法时,控制台的输出将会是:

31

题目 2

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }
    public static int test1() {
        try {
            return 2;
        } finally {
            return 3;
        }
    }
}

执行结果:3。

try 返回前先执行 finally,结果 finally 里不按套路出牌,直接 return 了,自然也就走不到 try 里面的 return 了。

注意:finally 里面使用 return 仅存在于面试题中,实际开发这么写要挨吊的(😂)。

题目 3(return 先执行还是 finally 先执行)

public class TryDemo {
    public static void main(String[] args) {
        System.out.println(test1());
    }
    public static int test1() {
        int i = 0;
        try {
            i = 2;
            return i;
        } finally {
            i = 3;
        }
    }
}

执行结果:2。

大家可能会以为结果应该是 3,因为在 return 前会执行 finally,而 i 在 finally 中被修改为 3 了,那最终返回 i 不是应该为 3 吗?

但其实,在执行 finally 之前,JVM 会先将 i 的结果暂存起来,然后 finally 执行完毕后,会返回之前暂存的结果,而不是返回 i,所以即使 i 已经被修改为 3,最终返回的还是之前暂存起来的结果 2。