Java中的final共有三种用法:
一、final成员变量
当你在类中定义变量时,在其前面加上final关键字,那便是说,这个变量一旦被初始化便不可改变,这里不可改变的意思对基本类型来说是其值不可变,
而对于对象变量来说其引用不可再变
,
但引用变量所指向的对象中的内容还是可以改变的
。
其初始化可以在三个地方,
一是其定义处,也就是说在final变量定义时直接给其
赋值,
二是在构造函数中。而且在Java1.1以前,只能是在定义时给值。
三是在初如化代码块中{} 或者 static{}
final变量和static变
量可以说
都只能存一个数据,他们惟一的区别是static变量是属于类的
,是类
变量,只会被加载一次。
final变量仍是个普通变量,属于实例变量,每创建一个对象还是会被加载一次
使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
还有一种用法是定义方法中的参数为final,对于基本类型的变量,这样做并没有什么实际意义,因为基本类型的变量在调用方法时是传值的,也就是 说你可以在方法中更改这个参数变量而不会影响到调用语句,然而对于对象变量,却显得很实用,因为对象变量在传递时是传递其引用,这样你在方法中对对象变量的修改也会影响到调用语句中的对象变量,当你在方法中不需要改变作为参数的对象变量时,明确使用final进行声明,会防止你无意的修改而影响到调用方法。
另外方法中的内部类在用到方法中的参变量时,此参变也必须声明为final才可使用,如下代码所示:
public class INClass {
void innerClass(
final String str
) {
class IClass {
IClass() {
System.out.println(str);
}
}
IClass ic = new IClass();
}
public static void main(String[] args) {
INClass inc = new INClass();
inc.innerClass("Hello");
}
}
final方法
将方法声明为final,那就说明你已经知道这个方法提供的功能已经满足你要求,不需要进行扩展,并且也不允许任何从此类继承的类来覆写这个方法,但是继承仍然可以继承这个方法,也就是说可以直接使用。
另外有一种被称为inline的机制,它会使你在调用final方法时,
直接将方法主体插入到调
用处,而不是进行例行的方法调用,例如保存断点,压栈等,这样可能会使你的程序效率有
所提高,然而当你的方法主体非常庞大时,或你在多处调用此方法,那 么你的调用主体代码便会迅速膨胀,可能反而会影响效率,所以你要慎用final进行方法定义。
类中所有的private方法从某种意义上讲都是属于final的,因为他们在其它地方没法覆盖,你可
以在一个private方法前加final修饰符,但没什么意义。
final类
当你将final用于类身上时,你就需要仔细考虑,因为一个final类是无法被任何人继承的
,那也就意味着此类在一个继承树中是一个叶子类,并且此类的设计已被认为很完美而不需要进行修改或扩展
。对于
final类中的成员变量,你可以定义其为final,也可以不是final
。
而对于方法,由于所属类为final的关系,自然也就成了final型的。你也可以明确的给final类中的方法加上一个final,但这显然没有意义。
附注:
final在设计模式中的应用
在设计模式中有一种模式叫做不变模式,在Java中通过final关键字可以很容易的实现这个模式,在讲解final成员时用到的程序Bat.java就是一个不变模式的例子。如果你对此感兴趣,可以参考阎宏博士编写的《Java与模式》一书中的讲解。