2020-12-21-Java-复习-62(final关键字)
2020-12-23 本文已影响0人
冰菓_
1.初始化的方式
public class Test4 {
public static void main(String[] args) {
}
}
class Fianl {
private final int a = 0;
private static final boolean b; //静态变量不能再普通代码块初始化
private final double c;
private final char d ;
//静态代码块初始化
static {
b = true;
}
//构造代码块
{
c = 1.1;
}
//构造方法初始化
Fianl(){
d =' ';
}
}
什么是fianl的不变性?
当final修饰基本数据类型变量时,不能对基本数据类型变量重新赋值,因此基本数据类型变量不能被改变。而对于引用类型变量而言,它仅仅保存的是一个引用,final只保证这个引用类型变量所引用的地址不会发生改变,即一直引用这个对象,但这个对象属性是可以改变的。
final修饰的变量表示赋值之后不能再进行更改,系统赋默认值也算赋值,因此系统也不会赋默认值。
为什么final字段可以“延迟“到构造方法中初始化?
对象或者类级别的字段其实是在构造方法或者static {}语句块中完成初始化的。这样一来,允许程序员把final字段"延迟"到构造方法或者static {}中初始化自然也是很正常的事了,因为本来就该如此。站在class文件结构的角度来看,字节码只是常量池中MethodRef,即方法引用常量的一个属性,因此如果我们在定义类/对象的字段时如果后面跟了赋值操作,那么这个操作的字节码别地方也没处待,只能放在常量池的方法引用常量中。这样的话放在构造方法或者static{}中就合情合理了。
2.执行顺序的测试
public class Test {
//谁在上面就先执行谁
static Test test = new Test();
static {
System.out.println("静态代码块");
}
//构造代码块
{
System.out.println("非静态代码块");
}
public static void main(String[] args){
System.out.println("开始执行");
Test test = new Test();
}
}