在任何一门计算机语言中,总有一个关键词来向编译器表示某块区域是不变的。在java中这一关键词是final,下面就讨论final的用法。
当用final修饰基本类型时表示这一域的值是编译时不变或者运行时不变的。所谓编译时不变就是用javac命令编译*.java文件时,用值替换掉final修饰的符号。并且在每次运行程序时这一变量的值都一样。其实是可执行文件中不存在这一变量了。
运行时不变是指,当final修饰的变量在编译时不能确定它的值,在运行之初确定其值,而后其值不能再被修改。
某类有如下变量:
private final int x = 1;
private static final int y = 2;
x、y都是在编译时就能确定的,而且差别不是很大。虽然y是static类型的,属于类变量,但是x也是不变的,所以不同对象的x、y值都是一样的。
但是:
private static Random rand = new Random();
private final int x = rand.nextInt();
public static final int y = rand.nextInt();
这时x、y是运行时才能确定的不变量,x和y的差别就必须要注意了。编译时x、y的值都不能确定,每次创建对象x的值都时通过运行rand.nextInt()得到,因此每个对象的x值不同;但是对于y,它是属于类变量,在加载*.class文件时确定其值,并且每个对象共享同一个y。
还有关于空白final的。在定义final变量时不进行初始化,待构建对象时才初始化。那就需要在构造函数中对final变量进行初始化,确保final域在使用前初始化,而后保持不变。显然,这里的final不能是static。
final修饰方法时,表示该方法在其导出类中不能被覆盖(override)。另外,private方法默认是final的,因为对其导出类它是不可见的,因此也不能被覆盖。在导出类中重新写一个在其基类中为private的方法,两者是完全无关的,调用也不会出现混乱。
final类表明该类无法被继承。其域是否为final类构建者根据情况决定。但其方法默认是final的。因为该类无法被继承,其包含的方法也就不能被覆盖(override)