[关闭]
@TryLoveCatch 2021-04-07T13:06:26.000000Z 字数 1315 阅读 626

Java基础之关键字

java java基础


final&finally&finalize

final

理解 Java 关键字 Final

修饰类

当一个类不想被继承时,就可以用final来修饰。

修饰方法

当一个方法不想被子类覆写(Override)时,可以用final来修饰。另外一方面,把方法用final来修饰也有一定的性能提升上的帮助,因为虚拟机知道它不会被覆写,所以可以以更简单的方式来处理。

private的方法,默认都会被编译器加上final.

修饰变量

final来修饰的第一个作用就是赋值后,不能再修改变量的值

成员变量

声明为final的成员变量必须在声明时初始化,或者在构造方法中初始化,否则会有编译错误。

匿名内部类使用final

  1. private void initViews() {
  2. final int a = 3; // Compilation error if remove final
  3. btn.setOnClickListener(new View.OnClickListener() {
  4. @Override
  5. public void onClick(View view) {
  6. if (a > 1) {
  7. // volala
  8. }
  9. }
  10. }
  11. }

匿名内部类使用外部变量时要强制使用final修饰,外部变量会以构造参数的形式传给内部类,因为这个变量内部类和外部类都使用了,所以,一方更改了,就会影响到另一方,所以必须为final的。

防止变量从构造方法中逸出

这个有一个线上的bug

  1. class A {
  2. public void test() {}
  3. }
  4. class B {
  5. private A a;
  6. public B() {
  7. // xxxx
  8. a = new A();
  9. }
  10. }
  11. 线程一执行:
  12. B b = new B();
  13. 线程二执行:
  14. if (b!=null) {
  15. b.a.test();
  16. }
  17. 报空指针异常

private final A a;就可以解决这个问题

jvm禁止编译器把final域的写重排序到构造函数之外。在对象引用为任意线程可见之前,对象的final域已经被正确初始化过了,而普通域不具有这个保障

对象实例化有是那个步骤:
1. 分配内存空间。
2. 初始化对象。
3. 将内存空间的地址赋值给对应的引用。

多线程环境下,如果2和3被重排序了,就有可能是1-3-2,那么B不为null,但是A可能还没有初始化

finally

finalize

对象不可达之后,如果对象没有覆盖finalize方法,或者finalize已经被执行过一次,则直接回收,反之,对象被加入一个队列,等待finalize线程来执行finalize方法,这个方法里面,如果重新与GCroot建立联系,则被移除队列,反之,就被回收

Parcelable Serializable

Android 进阶6:两种序列化方式 Serializable 和 Parcelable

一般在保存数据到 SD 卡或者网络传输时建议使用 Serializable 即可,虽然效率差一些,好在使用方便。

而在运行时数据传递时建议使用 Parcelable,比如 Intent,Bundle 等,Android 底层做了优化处理,效率很高。

Serializable会将父类 以及包名等各种信息都进行封装,比较大,而且只能用在java程序之间
Parcelable主要针对当前类,序列化可控,并且跨平台传输

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注