• java中final和finally和finalize的区别


    final、finally、finalize傻傻分不清楚,今天让你彻底弄清楚

    基础概念区分

    final

    修饰符

    1. 将类声明为final,意味着它不能再派生新的子类,不能作为父类被继承。final类中的所有成员方法都会被隐式地指定为final方法。

    (因此一个类不能及被声明为abstract,又被声明为final的。)
    2. 将方法声明为final,只能使用,不能被子类方法重写。
    3. 将变量声明为final,必须在声明时给定初值。如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

    finally

    异常处理语句结构的一部分,表示总是执行。

    try-catch-finally(可省略)

    finalize

    Object类的一个方法

    1. 在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
    2. 该方法更像是一个对象生命周期的临终方法,当该方法被系统调用则代表该对象即将“死亡”,但是需要注意的是,我们主动行为上去调用该方法并不会导致该对象“死亡”,这是一个被动的方法(其实就是回调方法),不需要我们调用。
    3. 在GC要回收某个对象时,这个对象:“最后一刻,我还能再抢救一下!”。因此JVM要对它进行额外处理。finalize成为了CG回收的阻碍者,导致这个对象经过多个垃圾收集周期才能被回收。
    public class Person {
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String toString() {
            return "姓名:" + this.name + ",年龄:" + this.age;
        }
    
        public void finalize() throws Throwable {//对象释放空间是默认调用此方法
            System.out.println("对象被释放-->" + this);//直接输出次对象,调用toString()方法
        }
    
    }
    
    class SystemDemo {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Person per = new Person("zhangsan", 30);
            per = null;//断开引用,释放空间
            //方法1:
            System.gc();//强制性释放空间
            //方法2:
    //        Runtime run=Runtime.getRuntime();
    //        run.gc();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    try、catch、finally执行顺序

    try、catch、finally为异常捕获结构,其中finally为非必需项,可有可无。当finally存在时,finally块中的代码都会执行。

    try-catch结构;
    try-catch-finally结构;
    try-finally结构也是可以的。

    特殊场景:
    仅在以下四种情况下不会执行finally块中语句。

    1. 如果在try或catch语句中执行了System.exit(0);
    2. 在执行finally之前jvm崩溃了
    3. try语句中执行死循环
    4. 电源断电

    不管有无异常,finally中代码都会执行

    public class FinallyTest {
        // 当传入参数str 为 "null" 时抛出异常
        public static void throwTest(String str) {
            if ("null".equals(str)) {
                throw new NullPointerException();
            }
        }
    
        public static String method(String str) {
            try {
                System.out.println("try");
                throwTest(str);
            } catch (Exception e) {
                System.out.println("exception: " + e);
            } finally {
                System.out.println("finally");
            }
            return str;
        }
    
        public static void main(String[] args) {
            System.out.println("-----无异常-----");
            method("nl");
            System.out.println("-----有异常-----");
            method("null");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    上述代码做了正常执行和抛出异常的测试,结果如下:

    -----无异常-----
    try
    finally
    -----有异常-----
    try
    exception: java.lang.NullPointerException
    finally
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    try中有return时,finally依然会执行

    public static String method(String str) {
        try {
            System.out.println("try--");
            return str;
        } catch (Exception e) {
            System.out.println("exception-- " + e);
        } finally {
            System.out.println("finally--");
        }
        return "end";
    }
    
    public static void main(String[] args) {
        System.out.println(method("str"));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    上述代码做了try中返回测试,结果如下:

    try--
    finally--
    str
    
    • 1
    • 2
    • 3

    finally对返回值的做修改,不会影响到try的返回值

    public static String method(String str) {
        try {
            System.out.println("try--");
            return str;
        } catch (Exception e) {
            System.out.println("exception-- " + e);
        } finally {
            System.out.println("finally--");
            str = "finally";
        }
        return "end";
    }
    
    public static void main(String[] args) {
        System.out.println(method("str"));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    上述代码做了在finally中修改返回值的测试,最终返回依然为"str",结果如下:

    try--
    finally--
    str
    
    • 1
    • 2
    • 3

    finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的。

    finally中包含return语句,程序会在finally中提前退出

    public static String method(String str) {
        try {
            System.out.println("try--");
            return str;
        } catch (Exception e) {
            System.out.println("exception-- " + e);
        } finally {
            System.out.println("finally--");
            str = "finally";
    
            // 在finally中的return 语句,会造成程序提前退出
            return str;
        }
    }
    
    public static void main(String[] args) {
        System.out.println(method("str"));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    上述代码做了在finally中,使用return语句的测试,程序会在finally中提前退出,结果如下:

    try--
    finally--
    finally
    
    • 1
    • 2
    • 3

    经典测试题

    面题目输出什么?

    public static int demo5() {
        try {
            return printX();
        }
        finally {
            System.out.println("finally trumps return... sort of");
        }
    }
    
    public static int printX() {
        System.out.println("X");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出结果:

    X
    finally trumps return... sort of
    0
    
    • 1
    • 2
    • 3

    上面这道题目含金量很高,程序顺序执行时先执行printX()函数,此时得到返回值0并且将0保存到variable中对应的用于保存返回值的区域;

    此时程序在执行finally语句因为finally语句中没有return语句,所以程序将返回值区域的0返回给上一级函数。

  • 相关阅读:
    骨传导耳机会损伤大脑吗?一分钟详细了解骨传导耳机
    Apache 部署配置
    风景园林设计专业要学哪些软件? 优漫动游
    使用SpringBoot集成Mybatis的详细步骤
    2.eureka的第一个实例(springcloud)
    【编码魔法师系列_构建型2.1】单例模式「饿汉式」(Singleton Pattern)
    安装淘宝镜像cnpm
    【R语言】概率密度图
    『CV学习笔记』图像超分辨率等图像处理任务中的评价指标PSNR(峰值信噪比)
    力扣(LeetCode)496. 下一个更大元素 I(C语言)
  • 原文地址:https://blog.csdn.net/guodong54/article/details/127955387