@TryLoveCatch
2021-04-07T21:06:26.000000Z
字数 1315
阅读 762
java
java基础
当一个类不想被继承时,就可以用final来修饰。
当一个方法不想被子类覆写(Override)时,可以用final来修饰。另外一方面,把方法用final来修饰也有一定的性能提升上的帮助,因为虚拟机知道它不会被覆写,所以可以以更简单的方式来处理。
private的方法,默认都会被编译器加上final.
final来修饰的第一个作用就是赋值后,不能再修改变量的值
声明为final的成员变量必须在声明时初始化,或者在构造方法中初始化,否则会有编译错误。
private void initViews() {
final int a = 3; // Compilation error if remove final
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (a > 1) {
// volala
}
}
}
}
匿名内部类使用外部变量时要强制使用final修饰,外部变量会以构造参数的形式传给内部类,因为这个变量内部类和外部类都使用了,所以,一方更改了,就会影响到另一方,所以必须为final的。
这个有一个线上的bug
class A {
public void test() {}
}
class B {
private A a;
public B() {
// xxxx
a = new A();
}
}
线程一执行:
B b = new B();
线程二执行:
if (b!=null) {
b.a.test();
}
报空指针异常
private final A a;
就可以解决这个问题
jvm禁止编译器把final域的写重排序到构造函数之外。在对象引用为任意线程可见之前,对象的final域已经被正确初始化过了,而普通域不具有这个保障
对象实例化有是那个步骤:
1. 分配内存空间。
2. 初始化对象。
3. 将内存空间的地址赋值给对应的引用。
多线程环境下,如果2和3被重排序了,就有可能是1-3-2,那么B不为null,但是A可能还没有初始化
对象不可达之后,如果对象没有覆盖finalize方法,或者finalize已经被执行过一次,则直接回收,反之,对象被加入一个队列,等待finalize线程来执行finalize方法,这个方法里面,如果重新与GCroot建立联系,则被移除队列,反之,就被回收
Android 进阶6:两种序列化方式 Serializable 和 Parcelable
一般在保存数据到 SD 卡或者网络传输时建议使用 Serializable 即可,虽然效率差一些,好在使用方便。
而在运行时数据传递时建议使用 Parcelable,比如 Intent,Bundle 等,Android 底层做了优化处理,效率很高。
Serializable会将父类 以及包名等各种信息都进行封装,比较大,而且只能用在java程序之间
Parcelable主要针对当前类,序列化可控,并且跨平台传输