面试官:介绍下final finally finalize的区别
你:这特么有什么关系吗?
面试官:没啥关系,就想这么问?说不说,不说滚!
你:说说说,大佬息怒。
final可以用来修饰类,字段,方法,可以用来限制类不被继承,字段值不被修改,方法不被重写。
finally是用来保证代码必定被执行的一种机制,常用try-finally,try-catch-finally来close jdbc连接,unlock锁等,无论try有无异常,return,都会执行finally方法,除非在这之前就停止了jvm,如System.exit(1),死锁啦,才不执行;
finalize是Object的方法,垃圾回收器会调用这个方法,用来在回收之前回收一些特定资源,也可以在这个方法里让对象再次对其他线程可见,fianlize里的异常不会抛出。
面试官:那final这么好,是不是可以用final来写immutable不可变类
你:final不等于immutable不可变类,不可变类要求很多,1. final修饰类,这样就不会被继承绕过去,2. 成员变量要是final并且是private的,而且不能有setter方法,3. 构造函数初始化时得用深度copy,因为输入的参数可能会被修改 4. get方法要用copy on write,创建私有的copy,避免返回任何内部的状态和引用,例如返回一个集合类的对象引用就会有被外部修改的风险。
面试官:嗯,你刚说的那个构造函数不能直接赋值,要深度copy,那 赋值,浅拷贝,深拷贝有啥区别?
你: 赋值 - 直接赋值
浅拷贝 - 拷贝基本类型和对象引用
深拷贝 - 拷贝基本类型,引用类型生成新的对象并拷贝自身属性,或者使用序列化来直接拷贝
面试官: 你刚还说了copy-on-write,这个介绍下.
你:就是一种延时策略,修改时copy一份生成一个新的容器,然后在新的容器里添加元素,这个操作是要加锁的。一般用在读多写少,非实时的情况下,只能保证最终一致性,不能保证过程中的一致性。
面试官:finalize有个新的替代方案,了解过吗?
你:java中有个Cleaner类就是用来代替它的,比finalize轻量,而且最重要的是它的线程是独立的,不会像finalize那样造成死锁。
面试官:Cleaner的实现原理是是什么?
你:利用了PhantomReference来实现的,配合ReferenceQueue将相关的资源都回收掉。
面试官:那reference都有哪些,介绍下?
你:强 软 弱 幻象引用。
强 Strong 对象创建后被一个或多个线程引用着。
软 Soft 可以避开一些垃圾回收,只有当内存不足时才会去回收它,可以保证缓存不会影响内存。
弱 Weak 不能避开垃圾回收,存在时直接返回对象,不存在时重新实例化。
幻象 Phantom 被finallize之后。
面试官:可以可以,那代替finally的方案了解过吗?
你:你说的是AutoClosable接口吧,实现了这个接口,可以在close方法,可以像finally关闭连接,回收一些资源。
面试官:那实现AutoClosable的对象是如何被回收的呢?
你:在try with resources结束的时候,close方法会被自动调用。