final、finally、finalize的区别

1 篇文章 0 订阅
1 篇文章 0 订阅

转载请注明链接:https://blog.csdn.net/feather_wch/article/details/82152236

final、finally、finalize的区别

版本号: 2018/8/28-1(16:57)


面试题

1、final、finally、finalize有什么不同?

  1. final: 可以修饰class、方法、变量
    1. final修饰的class无法被继承扩展
    2. final修饰的方法,无法被重写(overide)
    3. final修饰的变量,无法被更改
  2. finally: 用于try-catch,保证发生异常时会进行清理工作,如释放资源、执行unlock等操作。
  3. finalize:java.lang.Object的方法,本意是在GC前做一些回收工作,但是会造成性能急剧下降。
    1. JDK9中已经被废弃
    2. 执行时间不确定
    3. 严重影响GC性能(40~50倍)

final(7)

1、final的作用

  1. 可以修饰class、方法、变量
  2. final修饰的class无法被继承扩展
  3. final修饰的方法,无法被重写(overide)
  4. final修饰的变量,无法被更改

2、final的好处

  1. 保护代码,避免以外的编程错误。
  2. 防止别人去修改核心内容,导致功能不正确以及避免潜在的安全隐患

3、final能有助于JVM将方法内联,改善编译器进行条件编译的能力,从而提高性能?

错误!
1. 这种结论是基于猜测和假设
1. 现代高性能的虚拟机,如HotSpot非常智能,并不是通过final来判断是否能内联。

4、final修饰的变量就是常量?

错误!
1-修饰的基本数据类型,一旦赋值就无法改变。该变量必须要先初始化。

final int a = 10;

2-修饰的引用类型,可以间接修改。包括List等。

final StringBuilder a = new StringBuilder("aaaa");

StringBuilder b = a;
b.append(" 间接修改了final的引用a所指向的内容");

System.out.println(a+""); // 结果为: aaaa 间接修改了final的引用所指向的内容

5、如何创建一个immutable(不可变)的List?

final不具备immutable的特性:

final List<String> list = new ArrayList<>();
list.add("Hello");
list.add("final 阻止不了我");

利用Connections生成不可修改的集合:

List<String> immutable = Collections.unmodifiableList(list);
immutable.add("添加内容会报错");

实现immutable Class

6、如何实现immutable(不可改变)的类?

  1. final修饰class:避免通过扩展来绕开限制。
  2. private和final修饰所有成员变量,并且不要实现setter方法。
  3. 使用深拷贝来构造对象:不采用直接复制,避免被间接修改内容。
  4. getter等方法采用copy-on-write原则:将内容copy一份提供出去。

实际问题

7、匿名内部类中访问的局部变量为什么要用final?

  1. Java内部类会去copy一份变量,而不是采用局部变量。
  2. final能保证数据一致。

finally(7)

1、finally的作用

  1. 用于try-catch,保证发生异常时会进行清理工作,如释放资源、执行unlock等操作。
  2. 推荐使用Java 7的try-with-resources来替代finally
  3. 能有效避免finally丢失异常的情况。
  4. try-with-resources,采用语法糖来实现,编码量少且规范。

2、不要在finally处理会返回的数值、对象。

3、在try中调用break、continue、return都会进入finally

4、不要在try中去return返回值,否则一定要保证finally不会修改返回值(数值、对象)。

5、try中有return,也一定会去执行finally。

exit

6、finally和return、System.exit(1)的关系

  1. finally前执行return,还是会执行finally的内容。
  2. finally前执行System.exit(1),会立即退出,不会执行finally,然而这种场景并没有什么用。

7、finally在哪些情况中不会执行?

  1. System.exit(-1):异常退出
  2. try-catch中无限循环
  3. finally所处于的线程被杀死

finalize(6)

1、finalize的作用

  1. 本意是在GC前进行资源回事。
  2. 实际上Object.finalize()在Java 9中已经被废弃。
  3. 缺点非常明显:
    1. 无法保证finalize什么时候执行,是否满足预期。
    2. 会影响性能,且容易导致死锁等各种问题。
  4. 除了try-catch-finally和resources两种方法,还可以利用Java 9的cleaner机制。

致命缺点

2、finalize的性能极差

  1. 在专门的benchmark上测试,finalize在GC时间上,大约有40~50倍的性能差距。极差!
  2. 即使使用System.runFialization()也没有多大用途,finalize拖慢GC回收,甚至可能会导致OOM

3、finalize会掩盖资源回收时的异常信息

  1. 根据JDK的源码: java.lang.ref.Finalizer
  2. 资源回收时出现的异常,会通过Throwable捕获,并且不作任何处理!
try{
    // 资源回收工作
}catch (Throwable x){
    // 居然吞掉了Throwable
    super.clear();
}

替代品:Cleaner机制

4、有什么机制可以替换掉finalize?

  1. Java 平台正逐渐使用java.lang.ref.Cleaner来替换掉原有的finalize实现。
  2. Cleaner的实现利用了幻想引用(PhantomReference)
  3. 采用一种常见的post-mortem清理机制
  4. Cleaner利用幻想引用和引用队列,保证了对象销毁前的清理工作,比如关闭文件描述符等。
  5. 比finalize更加轻量、更加可靠

5、Cleaner的优点

  1. 每个Cleaner的操作都是独立的,有自己的运行线程,可以避免意外死锁等问题。

6、Cleaner依旧有缺陷

  1. 如果由于一些原因导致幻想引用堆积,同样会出现问题。
  2. 只适合作为最后的手段。

知识储备

1、Java 9 Cleaner机制

参考资料:https://docs.oracle.com/javase/9/docs/api/java/lang/ref/Cleaner.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值