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();
    }
}
上一篇下一篇

猜你喜欢

热点阅读