Java 创建不可变对象-final关键字的使用总结

来源:互联网 发布:深海逃生剧情 知乎 编辑:程序博客网 时间:2024/05/01 08:51

之前一直对final这个关键的功能,很模糊。在编程中很多次都是使用eclispe自动在变量前加的final关键字,一直对这个好奇,今天找了些资料,对final进行地深入学习。
严格地说final修饰的变量不可被改变,一旦获得了初始值,该final变量的值就不能被重新赋值,因此final修饰成员变量和修饰局部变量时有一定的不同。

1. final成员变量

一般的成员变量是随类初始化或对象初始化而初始化的。当类初始化时,系统会为该类的类field分配内存,并分配默认值。也就是说,当执行静态初始化块时可以对类Field赋初值;当执行普通初始化块、构造器时可对实例Field赋初值。因此,成员变量的初始值可以在定义该变量时指定默认值,也可以在初始化块、构造器中指定初始值。如果没有在以上各种情况下对类成员变量赋初值,那么系统将会给final 修饰的类成员变量,一个默认的值,比如:0、’\u0000’\、false或者null。(这时候其实final成员变量也就失去了存在的意义)。
归纳起来,使用final成员变量需要注意以下几个问题:
静态Field :必须在静态初始化块中或声明该Field时指定初始值
普通Field:必须在非静态初始化块、声明该Field或构造器中指定初始值
final修饰的类成员,程序员最好显示地指定其初始值

2. final局部变量
系统不会对局部变量进行初始化,局部变量必须由程序员显示初始化。因此使用final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值。但是只能初始化一次。

3. final修饰基本类型变量和引用类型变量的区别
1). 当final修饰基本变量类型时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变
2). 当final修饰引用类型变量时,final只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但是这个对象(对象的非final成员变量的值可以改变)完全可以发生改变

4. 可执行“宏替换”的final变量
对于一个final变量来说,不管它是类field、实例field,还是局部变量,只要该变量满足3个条件,这个final变量就不再是一个变量,而是相当于一个直接量。
1). 使用final 修饰符修饰
2). 在定义该field变量时指定了初始值
3). 该初始值可以在编译时就被确定下来

5. final修饰的方法不可以被重写,final修饰的类不可以有子类

0 0