谈谈final, finally, finalize有什么不同?

final 可以修饰类、方法、变量。 
1. 修饰类,这个类就不可以被继承
2. 修饰方法,这个方法就不能被override(注意和overload的区别)
3. 修饰变量,这个变量就不能被修改
final 不要用来被滥用,为了所谓优化性能,来到处考虑使用final,那就是跑偏了。

我们写代码最重要的一点就是写出的代码具有语义,final是一个具有很强语义的关键字。
但是,这里要注意一点,如果final用来修饰变量,那么只能说这个变量不可被修改,不能混淆成这个变量不可变(immutable),因为java中变量是分为两种的值变量和引用变量,假如final修饰了一个引用变量,那么只能说明这个引用变量不可以被修改,但并不是变量不可变。
例如:
final List<String> list = new ArrayList<>(); // 声明了一个不可被修改的变量list
list.add("hello");
list.add("world");

上面的代码说明了,list这个引用变量被final修饰,约束了这个list不能再被赋值,但是这个list可以随意的添加修改内容。

所以,有的人错误的使用final,在程序中初始化了一个list,认为这个list初始化之后,就不可以被添加任何元素了。如果是这样的场景,建议使用List.of("hello", "world")

finally 通常是用来保证代码一定被执行的,但是呢,有一种情况,finally就不能保证代码块中的代码一定会被执行。
try { System.exit(1);} finally {System.out.println("这行代码不会被执行");}

finalize 是java.lang.Object的一个方法, 是用来保证对象在被垃圾回收之前完成特定资源的回收,现在finalize已经不被建议使用,并且java 1.9已经标记为了@Deprecated。Object中的finalize 是个空方法,可以在idea中找下finalize的override,idea会一直读进度条找啊找很久,毕竟java中所有类都默认是Object的子类嘛,假如某个子类override了Object的finalize的方法,并且填充了实现,那么这个子类的finalize方法就是非空的,一旦出现非空的finalize方法,就会导致该子类对象在回收的时候变慢,因为finalize是在回收之前调用,那么实际上,如果调用方法中有大量的逻辑要处理,就会导致这个本该立即回收的子类对象,迟迟不会被回收,拖慢垃圾收集,导致大量对象的堆积,最终oom。所以,对于特定资源的回收场景,要不就是显示回收,要不就是利用线程池等技术尽量重用现有的资源,如果非要想使用对特定资源的回收,java官方建议使用java.lang.ref.Cleaner来替换掉finalize的实现。

猜你喜欢

转载自blog.csdn.net/u010372981/article/details/81229552
今日推荐