final的使用情况一般分为三种:数据、方法、类
final数据
final修饰的数据表示值不可变,引用不能改变。其中,对数据的修饰又分为:
1、final成员变量:由final修饰的类成员变量,如果是基础数据类型就表示不能改变它的值,但如果是已经初始化了的引用型变量,表示不能改变该对象的引用,但对象本身还是能够改变的。
例:
// 引用型变量是可以改变其引用的
public class Test13 {
// 基础数据类型是不允许被改变的
private final static int INDEX = 1;
private final static Value V1 = new Value(1);
public static void main(String[] args) {
//INDEX ++; // The final field Test13.INDEX cannot be assigned
// V1 = new Value(2);// Cannot make a static reference to the non-static field V1
V1.i = 2; // 改变对象本身是可以的,但不能改变对象的引用
}
}
class Value {
int i;
public Value(int i) {
this.i = i;
}
}
这里需要注意,既是final又是static的域(编译期常量),一般使用大写表示,同时字母间用下划线分隔。
2、空白final:无初始值的final成员变量,在使用前必须要对它进行赋值,也就是在使用前必须确保它被初始化。
3、final参数:由final修饰的方法参数,意味着无法改变方法参数引用指向的对象。如果是数值的话就意味着不能被修改(其实就是说不能改变其指向的常量池中的对象),如果是引用型参数,则意味着不能改变其指向的堆中的对象。
例:
public void Test(final int i) {
// i ++;
// The final local variable i cannot be assigned. It must be blank and not using a compound assignment
}
public void Test(final Value v) {
// v = new Value(2);
// The final local variable v cannot be assigned. It must be blank and not using a compound assignment
}
final方法
final方法表示禁止方法被覆盖,但还是允许重载方法,只是不允许继承的子类对该方法进行重写。
我看有的说final锁定的方法能够提高效率,转为内嵌调用,但事实上,如果你的方法很大,内嵌调用所带来的那些性能提高就会被极大的缩减,因为相对于花费在方法内部的时间量,那点速度提升就没那么明显了。
private其实都是隐式的指定为final的,因为它不能被子类所继承,也就不存在“覆盖”这一说法了。
final类
final类表示类不能被继承。同时,类中的方法也隐式的是指定为final,因为没有继承,它们也就不能被覆盖。