异常处理——finally的特点、作用及面试题

finally的特点:

(1) 是异常处理的一部分,用于释放资源;

(2) 一般来说,被finally控制的代码一定会执行;

(3) 特殊情况:如果在执行到finally之前jvm退出了(比如:System.exit(0),但是,请注意,return语句并没有让jvm退出),就不再执行了,只要jvm没有退出,finally里面的代码都会执行。

格式:

(1) try…catch…finally…
(2) try…catch
(3) try…catch…catch…
(4) try…catch…catch…finally
(5) try…finally

try…finally这种做法的目的是为了释放资源,但是异常没有处理。

直接catch和直接finally是不可以的,单独使用catch和finally是不可以的,它们必须有try的存在。

finally的作用:

用于释放资源,在IO流操作和数据库操作中会见到。

finally相关的面试题:

(1) final,finally和finalize的区别

a) final:最终的意思,可以修饰类、成员变量、成员方法、局部变量。

修饰类时,该类不能被继承;修饰成员变量时,该成员变量是常量,值不能被修改;修饰成员方法时,该成员方法不能被重写;修饰局部变量时,该局部变量是常量,值不能被修改。

b) finally:看finally的特点、格式、作用总结的知识点。

c) finalize:不是一个关键字,它是Object类中定义的一个方法,用于垃圾回收,该方法一般来说不需要我们来调用。

(2) 如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问是在return前还是return后。

答:会,前。其实,finally中的代码的执行,它不在catch中的return语句的前面,也不在catch中的return语句的后面,而在catch中的return语句的中间执行。

代码演示:

(1)如果在执行到finally之前jvm退出了(比如:System.exit(0)),那么finally中的代码就不再执行了。

package work_help;

public class Demo_return_finally {
    public static void main(String[] args) {
        Demo_finally();
    }
    /**
     * 当try或catch中有让JVM退出操作时,在这种情况下finally中的代码是不会执行的。
     */
    public static void Demo_finally() {
        try {
            System.out.println("Demo_fianlly_a");
            System.exit(0);
            System.out.println("Demo_fianlly_b");

        } finally {
            System.out.println("Demo_fianlly_finally");
        }
    }
}
输出结果:
Demo_fianlly_a

(2)如果在执行到finally之前jvm没有退出,但是,在执行到finally之前存在return语句

package work;

public class Demo_finally {
    public static void main(String[] args) {
        System.out.println(getInt());
    }

    public static int getInt() {
        int a = 1;
        try {
            //这个语句分母为零,会报异常。
            System.out.println(a / 0);
            a = 2;
        } catch (ArithmeticException e) {
            System.out.println("a1 = " + a);
            a = 3;
            System.out.println("a2 = " + a);
            return a;
        } finally {
            System.out.println("a3 = " + a);
            a = 4;
            System.out.println("a4 = " + a);
        }
        System.out.println("a5 = " + a);
        return a;
    }
}

运行结果:
a1 = 1
a2 = 3
a3 = 3
a4 = 4
3

第18行的rturn a;在程序执行到这一步的时候,这里不是return a;而是return 3;这个返回路径就形成了。但是,它发现后面还有finally,所以,继续执行finally的内容,a = 4;然后,再次回到以前的返回路径,继续走return 3;

再看一个例子:

package zongjie;

public class Finally_return {
    public static void main(String[] args) {
        System.out.println(test());
    }

    private static int test() {
        int i = 0;
        try {
            String str = null;
            // 这句话会报:NullPointerException,即空指针异常
            str.getBytes();
            return i++;
        } catch (Exception e) {
            System.out.println("catch i == " + i);
            return ++i;
        } finally {
            System.out.println("finally i == " + i);
            return ++i;
        }
    }
}
运行结果:
catch i == 0
finally i == 1
2

其实,finally中的代码的执行,它不在return语句的前面,也不在return语句的后面,而在return语句的中间执行。

(3)如果finally之前有return语句,并且finally中同时也有return语句,则return语句只有一个执行。

package work;

public class Demo_finally {
    public static void main(String[] args) {
        System.out.println(getInt());
    }

    public static int getInt() {
        int a = 1;
        try {
            System.out.println(a / 0);
            a = 2;
        } catch (ArithmeticException e) {
            System.out.println("a1 = " + a);
            a = 3;
            System.out.println("a2 = " + a);
            return a;
        } finally {
            System.out.println("a3 = " + a);
            a = 4;
            System.out.println("a4 = " + a);
            return a;
        }
    }
}

运行结果:
a1 = 1
a2 = 3
a3 = 3
a4 = 4
4

猜你喜欢

转载自blog.csdn.net/G_66_hero/article/details/82655842