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做内存回收。

相关文章
|
存储 Java
java对两个字符串进行比较,分别取出重复和不重复的。
java对两个字符串进行比较,分别取出重复和不重复的。
446 0
|
缓存
内存学习(三):物理地址空间
内存学习(三):物理地址空间
440 0
|
Java
如何使用 try-catch 块来捕获静态变量初始化中的异常
在Java中,可以通过在静态初始化块或静态变量初始化时使用try-catch语句来捕获可能出现的异常,确保程序的健壯性。具体做法是在静态初始化代码中加入try-catch结构,对可能抛出的异常进行处理。
298 16
|
Prometheus 运维 监控
解锁分布式云多集群统一监控的云上最佳实践
为应对分布式云多集群监控的挑战,阿里云可观测监控 Prometheus 版结合 ACK One,凭借高效纳管与全局监控方案有效破解了用户在该场景的监控运维痛点,为日益增长的业务需求提供了一站式、高效、统一的监控解决方案,实现成本与运维效率的双重优化。助力企业的数字化转型与业务快速增长,在复杂多变的云原生时代中航行,提供了一个强有力的罗盘与风帆。
56477 115
|
Java
如何捕获和处理 EOFException 异常
EOFException 异常通常在尝试从输入流中读取数据但已到达文件末尾时抛出。要捕获和处理该异常,可以使用 try-catch 语句块,在 catch 块中进行相应的错误处理或提示。例如: ```java try { // 读取数据的代码 } catch (EOFException e) { System.out.println(&quot;已到达文件末尾&quot;); } ```
580 4
|
Java 数据库连接 数据库
【MyBatis】进一步理解choose、when、otherwise标签
【MyBatis】进一步理解choose、when、otherwise标签
673 0
|
数据采集 前端开发 Java
@ControllerAdvice:你可以没用过,但是不能不了解
`@ControllerAdvice` 是 Spring MVC 中用于定义全局行为的注解,如异常处理、数据绑定和预处理。它从 `@Component` 派生,确保被扫描并纳入容器。`@ExceptionHandler` 用于全局异常处理,提供统一的错误响应。例如,当处理不当的异常时,它能返回友好的错误信息。`@InitBinder` 在数据绑定前对参数进行处理,如格式转换。`@ModelAttribute` 可以用于全局绑定模型属性,如登录用户信息。Spring MVC 通过 `DispatcherServlet` 和 `HandlerAdapter` 在请求处理流程中应用这些全局配置。
630 3
@ControllerAdvice:你可以没用过,但是不能不了解
|
Java
Java list中的对象转为list,list中的对象转为map
Java list中的对象转为list,list中的对象转为map
790 1
|
机器学习/深度学习 算法 atlas
RAG 2.0架构详解:构建端到端检索增强生成系统
RAG(检索增强生成)旨在通过提供额外上下文帮助大型语言模型(LLM)生成更精准的回答。现有的RAG系统由独立组件构成,效率不高。RAG 2.0提出了一种预训练、微调和对齐所有组件的集成方法,通过双重反向传播最大化性能。文章探讨了不同的检索策略,如TF-IDF、BM25和密集检索,并介绍了如SPLADE、DRAGON等先进算法。目前的挑战包括创建可训练的检索器和优化检索-生成流程。研究表明,端到端训练的RAG可能提供最佳性能,但资源需求高。未来研究需关注检索器的上下文化和与LLM的协同优化。
1895 1
JAVA——List中剔除空元素(null)的三种方法汇总
JAVA——List中剔除空元素(null)的三种方法汇总

热门文章

最新文章