Java核心 -- final + finally + finalize

栏目: Java · 发布时间: 5年前

内容简介:Java目前没有
  1. 修饰 ,代表不可以 继承扩展
  2. 修饰 变量 ,代表变量不可以 修改
  3. 修饰 方法 ,代表方法不可以 重写

实践

  1. 推荐使用 final 关键字来 明确表示 代码的语义和逻辑意图
  2. 将方法或类声明为 final ,明确表示不允许重写或继承
  3. 使用 final 修饰参数或变量,能够避免意外赋值而导致的编程错误
  4. final 变量产生了某种程度的 不可变 (immutable)的效果,可以用于保护只读数据
  5. 现在 JVM 足够智能, final 对性能的影响,在大部分情况下,都没有必要考虑 ,应用程序更应该关注的是 语义

final != immutable

Java目前没有 原生的immutable支持

// final只能约束strList这个引用不可以被赋值,但strList对象本身的行为是不受影响的
final List<String> strList = new ArrayList<>();
strList.add("Hello");
strList.add("World");
// since 9
List<String> unmodifiableStrList = List.of("Hello", "world");
// throw java.lang.UnsupportedOperationException
unmodifiableStrList.add("again");

immutable类

  1. final class
  2. 所以成员变量定义为 private final ,并且不要实现 setter 方法
  3. 构造对象时,成员变量使用 深度拷贝 来初始化
    • 防御编程:因为无法确保输入对象不会被其它线程修改
  4. 如果需要实现 getter ,使用 copy-on-write 原则

finally

  1. 保证重点代码 一定要被执行 的一种机制
  2. try-finallytry-catch-finally
  3. try-with-resources (JDK 7引入)
try {
    System.exit(-1);
} finally {
    // 不会执行
    System.out.println("Print from finally");
}

finalize

  1. java.lang.Object 中的一个 protected 方法
  2. 设计目标: 保证对象在被GC前完成特定资源的回收
  3. 不推荐使用,在 JDK 9 中已经被标记为 @Deprecated(since="9")
  4. 无法保证 finalize() 何时会执行,执行的结果是否符合预期
    • 如果使用不当会影响性能,导致程序死锁、挂起等问题
  5. 一旦实现类非空的 finalize 方法,会导致对象回收呈现 数量级 上的变慢(40~50倍)
  6. 实现了 finalize 方法的对象是 特殊公民 ,JVM需要对它们进行额外的处理
    • finalize 本质上成为了 快速回收的阻碍者
    • 可能导致对象经过多个 GC周期 才能被回收
  7. System.runFinalization() 同样是不可预测的
  8. 实践中, finalize 会拖慢GC,导致 大量对象堆积 ,有可能导致 OOM
  9. 对于消耗非常高频的资源,不要指望 finalize 去承担释放资源的主要职责
    • 推荐做法: 资源用完即显式释放 ,或者利用 资源池 来复用
  10. 另外, finalize掩盖资源回收时的出错信息
java.lang.ref.Finalizer
// Throwable被生吞
private void runFinalizer(JavaLangAccess jla) {
    ...
    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();
}

替代方案 – Cleaner

  1. Java平台逐渐使用 java.lang.ref.Cleaner 替换掉原有的 finalize 实现
  2. Cleaner 的实现利用了 幻象引用 (Phantom Reference)
    • 利用 幻象引用引用队列 ,保证对象被 销毁之前 做一些类似资源回收的工作
  3. Cleanerfinalize 更加 轻量 ,更加 可靠
  4. 每个 Cleaner 的操作都是 独立 的,都有 自己的运行线程 ,可以 避免意外死锁 等问题
  5. 可预测 的角度来判断, Cleaner 或者 幻象引用 改善的程度依然是有限的
    • 由于种种原因导致 幻象引用堆积 ,同样会出现问题
    • Cleaner 适合作为 最后的保证手段 ,而 不能完全依赖 Cleaner 进行资源回收
public class CleaningExample implements AutoCloseable {
    // A cleaner, preferably one shared within a library
    private static final Cleaner cleaner = Cleaner.create();

    // State定义为static,为了避免由于普通的内部类隐含对外部对象的强引用,而导致外部对象无法进入幻象可达的状态
    static class State implements Runnable {
        State() {
            // initialize State needed for cleaning action
        }

        @Override
        public void run() {
            // cleanup action accessing State, executed at most once
        }
    }

    private final State state;
    private final Cleaner.Cleanable cleanable;

    public CleaningExample() {
        this.state = new State();
        this.cleanable = cleaner.register(this, state);
    }

    @Override
    public void close() {
        cleanable.clean();
    }
}

以上所述就是小编给大家介绍的《Java核心 -- final + finally + finalize》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

P3P Web隐私

P3P Web隐私

克劳娜著、技桥译 / 克劳娜 / 清华大学出版社 / 2004-5 / 45.0

自万维网络中出现商业站点以来,基于Web的商业需求和用户的隐私权利之间就存在着不断的斗争。Web开发者们需要收集有关用户的信息,但是他们也需要表示出对用户隐私的尊重。因此隐私偏好工程平台,或者称之为P3P,就作为满足双方利益的技术应运而生了。 P3P由万维网协会研制,它为Web用户提供了对自己公开信息的更多的控制。支持P3P的Web站点可以为浏览者声明他们的隐私策略。支持P3P的浏览......一起来看看 《P3P Web隐私》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码