Java中的关键字final、finally与finalize方法

Java中有很多关键字,这些关键字中的final、finally和finalize()方法长相十分相似,其实他们仨并没什么特殊的联系,只是单纯的像,本文就简单介绍下他们仨各自的用途。

final

final关键字可用于非抽象类、非抽象类的成员方法(构造方法除外)、非抽象类中的变量、参数

  • 用于类:表示该类不可被继承,类中的方法默认都是被final修饰的方法(例如String类)
  • 用于方法:表示该方法不可被子类重写(例如Object.getClass()方法)
  • 用于变量:表示常量,只能被赋值一次不可改变
  • 用于参数:该参数在方法中只可以被读取不可被修改

注:final修饰变量时,被修饰的变量是常量,该变量名全部大写;可以先声明不进行赋值值,这种叫做final空白。但是使用前必须被初始化。一旦被赋值,将不能再修改

修饰基本类型变量和引用类型变量

  • 修饰基本类型变量时:不能对基本类型重新赋值。
  • 修饰引用型变量时:它仅仅保存的是一个引用,final保证的是这个引用类型的变量所引用的地址不会变。即一直引用同一个对象,但是被引用对象的值可以改变。
/**
 * 描述: final修饰变量示例
 *
 * @author zhengql
 */
public class Demo {
    public static void main(String[] args) {
        final int num = 10;
        //编译报错,无法为最终变量num分配值
        //num+=1;
        System.out.println(num);

        final Person person = new Person("张三",20);
        System.out.println(person.toString());
        person.setName("李四");
        System.out.println(person.toString());
    }

    static class Person{
        private String name;
        private int age;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public Person setName(String name) {
            this.name = name;
            return this;
        }

        public int getAge() {
            return age;
        }

        public Person setAge(int age) {
            this.age = age;
            return this;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
}

运行示意图如下:

image

finally

try-catch想必大家都用过,finally必定不会陌生,finally只有在出现try-catch的地方才会用到,而且不一定会用到。我们一般用到它的时候应该是这样:

        try {
            //......
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //.......
        }

理解finally记住下面这就话就够了:

try-catch中无论是否发生异常,finally中的逻辑都会执行。
finally可有可无。但是必须与try-catch成对出现。

finalize

首先需要说明的是:finalize()方法本身存在一定的缺陷性,
实际使用中也不推荐finalize方法,在Java9中finalize已经被废弃

finalize()方法是在Object类中定义的,Java中所有类都从Object类中继承finalize()方法。垃圾回收器准备释放对象占用的内存时,首先调用对象的finalize()方法

finalize()与C++ 中的析构函数是不一样的。C++中的析构函数调用的时机是确定的(对象离开作用域或调用delete),但Java由于gc的执行时间不确定导致finalize的调用具有不确定性

Java有垃圾回收器(GC)负责回收无用对象占据的内存空间。但也有特殊情况:假定你的对象(并非使用new)获得了一块“特殊”的内存区域,由于垃圾回收期只知道释放那些经由new分配的内存,所以它不知道该如何释放该对象的这块“特殊”内存。所以Java的设计者准备了finalize()方法来解决这个问题,但是finalize也带来了一些隐患

finalize存在的问题

  • 不可靠:只有当垃圾回收器(GC)释放该对象时才会调用finalize方法,然而GC并不是想执行就执行的(根据程序当前是否内存不足),而且即使调用了finalize方法也不一定回收成功
  • 阻碍GC的快速回收:在进行垃圾回收时会启动一个finalizethread,当遇到有重写了finalize方法的对象时,会将对象放入finalizethread的中,并形成一个队列,暂时挂起,且运行时间并不确定,这就导致了对象回收的缓慢,如果队列中存在重写的finalize方法有死锁问题则会导致后面的方法都无法执行
  • 会发生对象复活现象:finalize方法中,可将待回收对象赋值给GC Roots可达的对象引用,从而达到对象再生的目的

关于finalize的生命周期和代码示例,此处推荐一篇很详细的文章:finalize的执行过程(生命周期)

参考

Java中finalize()详解和Java9中的垃圾回收:https://blog.csdn.net/u011695358/article/details/78860410

finalize()的使用场景:https://segmentfault.com/q/1010000000094660

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值