71.final关键字
在Java的类、方法和变量前面,可以加上final关键字。final关键字表示它修饰的类、方法或变量不可被改变。
在很多笔试题目中,喜欢拿final关键字来做文章。
1 final类
final类不可以被继承,比如java.lang.Math。如果你不希望你的类被继承,可以将类定义为final类,这样,别的类就无法继承它。
2 final变量
final 变量表示该变量不可以被改变。其实就是常量,因为在Java中不能使用const保留字来定义常量,所以,在需要使用常量的场合,可以使用final关键字来修饰。
比如:
final int CONST_VAR=12;
如果final变量是简单类型的变量,那么,变量的值一旦初始化后,就不能被改变;如果 final变量是引用类型的变量,那么,你不能改变这个变量的引用,但可以改变这个变量所引用的对象的属性。
我们来看下面这个例子:
class Aclass {
private int a;
// 构造器
public Aclass() {
a = 100;
}
public void setA(int theA) {
a = theA;
}
public int getA() {
return a;
}
}
// 定义一个类来测试final应用变量
public class TestFinal {
final Aclass aClass = new Aclass();
public static void main(String[] args) {
TestFinal tf = new TestFinal();
tf.aClass.setA(1);
System.out.println(tf.aClass.getA());
}
}
在这个例子中,我们定义了一个类Aclass,这个类有一个实例变量a,并且有相应的存取方法来对它进行存取。然后,在类TestFinal中,我们定义了一个final的应用类型的变量aClass,这个变量的引用是不能被改变的,但是,我们可以将这个引用变量指向的对象的属性进行修改,在这边,我们通过调用实例的setA方法来修改它的实例变量a,这样,这个时候这个静态引用变量指向的对象的属性值被修改成了1。
在编程实践中,我们还经常用静态常量,也就是同时用static 和final来修饰的“变量”,例如,在前面我们频繁使用的用于向标准设备输出信息的语句:
System.out.println(…);
在这里,System.out的关系是:out是System类的一个静态常量,所以可以不需要实例化System就可以直接通过“类名.属性”的方式来访问它。
提示:
根据Java命名规范,如果在编译的时候,就可以确定final变量的值,那么,此常量的名字应该都大写,并且指出完整含义,如果需要用几个单词描述,那么单词之间用“_”来分割,如:static final int MAX_TAX_RATE = 20;
相反的,在下面情况下可以不使用上面的命名规则: final变量无法在编译的时候就获得值,而必须在执行的时候才能得到值,比如,我们在示例7-4中的final变量aClass就是一个例子:final Aclass aClass = new Aclass();在编译的时候,程序不会执行new动作来实例化一个Aclass,并赋值给aClass,所以,就没有使用上面的命名规则来给final变量命名。
3 final方法
final方法表示这个方法不可以在子类中覆盖。比如,下面的例子中,类B编译不会通过,因为它试图覆盖赋类中的一个final方法:
父类:
public class A{
public final void methodA(){ … …}
//… …
}
子类:
public class B extends A {
//此处报错,因为它试图覆盖父类中的静态方法
public void methodA()
{ … … }
}
如果将父类A中的methodA()改成private的,如下:
父类:
public class A {
private final void methodA()
{ … …}
… …
}
子类:
public class B extends A {
//此处不报错,因为它只是定义了一个methodA()
public void methodA()
{ … …}
}
注意类A中的methodA(),它的访问修饰符为private,此时,在子类B中是访问不了父类A的methodA()方法的,因此,在类B中的methodA()只是新定义的一个方法而不是覆盖父类的方法。所以,此时编译这个程序将不会报错。
下一篇: 学习编程,API很重要么?