开发者社区> 王小明hit> 正文

final 、finally、finalize有什么区别

简介: final 、finally、finalize有什么区别
+关注继续查看

final 是可以用来修饰类、方法、变量、分别不同的意义。 

  • final 修饰的类class代表不可以继承
  • final 修饰的变量表示不可修改
  • final 修饰的方法表示不可重写(override)

finall 是Java中保证代码一定要被执行的一种机制,我们可以使用 try-finally 或者 try-catch-finally 来进行类似关闭JDBC,unlock 锁等动作。

finalize 是基础类 java.lang.object 的一个方法,他的设计目的是保证对象在垃圾收集前完成特定资源的回收。finalize机制不推荐使用。JDK9 被标记为 deprecated。



final使用有什么好处?


final 变量产生了某种程序的不可变效果,可以用来保护只读数据。尤其在并发编程中,可以明确地不能赋值 final 变量,有利于减少额外的同步开销。


try{
            // do something
            System.out.println("do Something");
            // system.exit(0):正常退出,程序正常执行结束退出
            // system.exit(1):是非正常退出,就是说无论程序正在执行与否,都退出,
            System.exit(1);
        }finally{
            System.out.println("Print from finally");
        }


这个比较特殊 上面 finally 里面的代码不会被执行。


如何实现一个不可变类

将class 本身声明为 final ,这样就不能被继承扩展

将所有成员变量定义为 private 和 final ,并且不要实现 setter

通常构造对象是,成员变量使用深度拷贝来初始化,而不是直接赋值。因为你无法确定输入对象不被其他人修改。

如果确实需要实现getter 方法。获知其他可能返回内部状态的方法,使用 copy-on-write (写时复制)原则。Java 有 CopyOnWriteArrayLIst 实现


栗子:

public boolean add(T e) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        int len = elements.length;
        // 复制出新数组
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        // 把新元素添加到新数组里
        newElements[len] = e;
        // 把原数组引用指向新数组
        setArray(newElements);
        return true;
    } finally {
        lock.unlock();
    }
}
final void setArray(Object[] a) {
    array = a;
}


为啥说不推荐使用  finalize?


Java 平台正在使用 java.lang.Cleaner 类替换 finalize 实现 ,Cleaner 的实现使用 虚引用(PhantomRefrence),这个是一种常见的所谓 post-mortem 清理机制。


主要原因是 finalize 会掩盖资源回收时的出错信息 看 java.lang.ref.Finalizer 源码


private void runFinalizer(JavaLangAccess jla) {
        synchronized (this) {
            if (hasBeenFinalized()) return;
            remove();
        }
        try {
            Object finalizee = this.get();
            if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
                jla.invokeFinalize(finalizee);
                /* Clear stack slot containing this variable, to decrease
                   the chances of false retention with a conservative GC */
                finalizee = null;
            }
        } catch (Throwable x) { }
        super.clear();
    }



Throwable 生吞了一切已成,及时出现异常或者出错,也得不到任何有效信息。


JDK9 平台使用了 Clearner 来替换原来的 finalize 实现


public class CleaningExample implements AutoCloseable {
        // A cleaner, preferably one shared within a library
        private static final Cleaner cleaner = <cleaner>;
        static class State implements Runnable {
            State(...) {
                // initialize State needed for cleaning action
            }
            public void run() {
                // cleanup action accessing State, executed at most once
            }
        }
        private final State;
        private final Cleaner.Cleanable cleanable
        public CleaningExample() {
            this.state = new State(...);
            this.cleanable = cleaner.register(this, state);
        }
        public void close() {
            cleanable.clean();
        }
    }



Cleaner 采用 虚引用技术,但是我们平时还是尽量不怎么用,这个只是最后的保障。并不能完全依赖 Cleaner做内存回收。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
19723 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
29028 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
22504 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
20659 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
16373 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14895 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
20895 0
+关注
227
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载