#final field:
-
编译期常量,永远不可改变。
-
运行期初始化时,我们希望它不会被改变。
对于编译期常量,它在类加载的过程就已经完成了初始化,所以当类加载完成后是不可更改的,编译期可以将它代入到任何用到它的计算式中,也就是说可以在编译期执行计算式。当然对于编译期常量,只能使用基本类型,而且必须要在定义时进行初始化。
有些变量,我们希望它可以根据对象的不同而表现不同,但同时又不希望它被改变,这个时候我们就可以使用运行期常量。对于运行期常量,它既可是基本数据类型,也可是引用数据类型。基本数据类型不可变的是其内容,而引用数据类型不可变的是其引用,引用所指定的对象内容是可变的。
##Demo
public class FinalDemo { private final String final1 = "Hotk"; private final String final2; private final int final3 = new Random().nextInt(10); private final Animal final4 = new Animal(1001, "ys"); private static final String final5 = "hs"; public FinalDemo(String final2) { this.final2 = final2; } @Override public String toString() { return "FinalDemo{" + "final1='" + final1 + '\'' + ", final2='" + final2 + '\'' + ", final3=" + final3 + ", final4=" + final4 + '}'; } public static void main(String[] args) { FinalDemo demo1 = null; FinalDemo demo2 = null; System.out.println("下面开始实例化!"); demo1 = new FinalDemo("demo1"); demo2 = new FinalDemo("demo2"); demo1.final4.setName("demo1"); demo2.final4.setName("demo2"); System.out.println(demo1); System.out.println(demo2); }}class Animal { private int id; private String name; public Animal(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Animal{" + "id=" + id + ", name='" + name + '\'' + '}'; }}
下面开始实例化!FinalDemo{final1='Hotk', final2='demo1', final3=3, final4=Animal{id=1001, name='demo1'}}FinalDemo{final1='Hotk', final2='demo2', final3=9, final4=Animal{id=1001, name='demo2'}}
#final method 所有被 final 标注的方法都是不能被继承、更改的,所以对于 final 方法使用的第一个原因就是方法锁定,以防止任何子类来对它的修改。至于第二个原因就是效率问题 #final class 如果某个类用 final 修改,表明该类是最终类,它不希望也不允许其他来继承它。在程序设计中处于安全或者其他原因,我们不允许该类存在任何变化,也不希望它有子类,这个时候就可以使用 final 来修饰该类了。
对于 final 修饰的类来说,它的成员变量可以为 final,也可以为非 final。如果定义为 final,那么 final 数据的规则同样适合它。而它的方法则会自动的加上 final,因为 final 类是无法被继承,所以这个是默认的