对Java中 final、finally、finalize的理解

摘要

极客时间里的Java核心技术系列,第3讲,记录一些笔记。
关键词:copy-on-write,System.exit(1),幻象引用,OOM

final

使用 final 来明确我们代码的语义,或者逻辑意图:
final 修饰的类,不可继承。
final 修饰的方法,不可重写。
final 修饰的变量,不可改变

但需要注意: final 变量 不等于 immutable, 比如:

// final 只能约束 list引用 不能被重新赋值,但是list对象的行为不受影响。
final List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
// List.of() 方法 创建的是 不可变的list
List<String> unmodifiableList = List.of("list of");
umodifiableList.add("unmodify")

Java目前没有原生的对immutable的支持。如果需要实现 不可变的类,需要做到:

  • class 用 final 修饰。
  • 成员变量都用 final,private修饰。
  • 构造对象用 深拷贝。
  • 不实现setter方法。对于getter方法,如果实在想用,需要遵守 copy-on-write 原则。
copy-on-wirte(写时复制) 原则:

是一种程序设计的优化方案,是一种延时懒惰的策略。

很多人共享同一容器,当某人想要修改时,把他复制出去形成新的容器,在新的容器里面修改,改好了再将 原容器的引用 指向 新容器。

finally

finally 是Java中保证重要代码一定要执行的一种机制。
可以用来关闭资源(文件关闭,JDBC连接等等) 或者 unlock锁。
但是 JDK7添加的 try-with-resources 语句 要更好用些。

  • 特例:
try{
   
	// do something...
	System.exit(1);
}finally{
   
	// 系统退出(exit)了,这个语句不会被执行。。。
	// 但是对于系统返回(return)了,是会执行 finally 里的语句的。
	System.out.println("execute finally。。。");
}

finalize

finalize 在 JDK9 已经被标记为 deprecated 了。

为什么会 deprecated:

当然是实践证明不好用。。。

一旦实现了 非空finalize 方法,就会导致 对象回收 呈现 数量级上的变慢,约40-50倍的下降。
所以会拖累 垃圾收集器,导致大量对象堆积,容易发生 OutOfMemoryError。

替换成 java.lang.ref.Cleaner 。利用了幻象引用和引用队列,可以保证对象被销毁前 做一些类似 资源回收 的工作。

JDK1.2 开始,对象的引用分为 4 个级别:
  • 强引用
    好比于 必不可少的生活用品。宁愿发出 OOM 错误,也不愿回收的对象。
  • 软引用(SoftReference)
    好比于 可有可无的生活用品。可以和 引用队列 联用
    垃圾收集器工作了,扫描到它时,内存够就不回收,内存不够就把它回收誊内存出来。
  • 弱引用(WeakReference)
    和 软引用 很像。 可以和 引用队列 联用
    垃圾收集器工作了,扫描到它时,就会把它回收了。
  • 虚引用(幻象引用) (PhantomReference)
    形同虚设,和没有引用差不多。 必须和 引用队列 联用

参考链接:

http://ifeve.com/java-copy-on-write/
https://juejin.im/post/5bd96bcaf265da396b72f855
https://blog.csdn.net/hnhygkx/article/details/80182906

全部评论

相关推荐

06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-09 13:05
TMD找工作本来就烦,这东西什么素质啊😡
Beeee0927:hr是超雄了,不过也是有道理的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务