final关键字
final 被译为 “最后的”、“最终的”,final 是 Java 语言中的一个关键字,凡是被 final 关键字修饰过的内容都是不可改变的。本节将讲解 final 关键字的 3 种使用场景。
final关键字
final 关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。通常,由final 关键字定义的变量为常量。例如,在类中定义 PI 值,可以使用如下语句:
final double PI = 3.14;
当在程序中使用了 PI 这个常量时,它的值就是 3.14。如果在程序中再次对定义为 final 的常量进行赋值,那么编译器将不会接受。
由 final 关键字定义的变量必须在声明时对其进行赋值操作。final 关键字除了可以修饰基本数据类型的常量,还可以修饰对象引用。由于数组也可以被看作一个对象来引用,因此 final 关键字可以修饰数组。一个对象引用一旦被修饰为 final 关键字后,它就只能恒定指向一个对象,无法将其改变以指向另一个对象。一个既是 static 又是 final 的字段只占据一段不能改变的存储空间。为了深入了解 final 关键字,来看下面的实例。
【例7.10】定义不允许被修改的常量π(实例位置:资源包\TM\sl\7\10)
创建 FinalData 类,在该类中定义表示圆周率的常量 PI,并尝试修改 PI 的值。
public class FinalData {
static final double PI = 3.1415926;
public static void main(String[] args) {
System.out.println("圆周率的值为:" + PI);
System.out.println("半径为3的圆的周长为:" + (2*3*PI));
PI = 3.1415927; // 尝试修改PI的值
}
}
本实例在运行之前,Eclipse 就会报出如图7.7所示的编译错误。常量 PI 不允许被修改。

final方法
将方法定义为 final 类型,可以防止子类修改父类的定义与实现方式,同时定义为 final 的方法的执行效率要高于非 final 方法。在修饰权限中曾经提到过 private 修饰符,如果一个父类的某个方法被设置为 private,子类将无法访问该方法,自然无法覆盖该方法。也就是说,一个定义为 private 的方法被隐式地指定为 final 类型,因此无须将一个定义为 private 的方法再定义为 final 类型。例如下面的语句:
private final void test() {
... // 省略一些程序代码
}
【例7.11】使用final关键字为电视机上儿童锁(实例位置:资源包\TM\sl\7\11)
创建 Dad 爸爸类,给 Dad 类定义一个打开电视机的方法,该方法使用 final 关键字修饰。创建 Dad 类的子类 Baby 类,让 Baby 类尝试自己重写打开电视的方法。
class Dad {
public final void turnOnTheTV() {
System.out.println("爸爸打开了电视");
}
}
class Baby extends Dad {
public final void turnOnTheTV() {
System.out.println("宝宝也要打开电视");
}
}
本实例在运行之前,Eclipse 就会报出如图7.8所示的编译错误。因为打开电视这个方法是由 final 关键字修饰的,子类无法被重写。所以 Baby 想要打开电视,就只能找爸爸来打开了。

final类
定义为 final 的类不能被继承。如果希望一个类不被任何类继承,并且不允许其他人对这个类进行任何改动,可以将这个类设置为 final 类。final 类的语法如下:
final 类名{}
如果将某个类设置为 final 类,则该类中的所有方法都被隐式地设置为 final 方法,但是 final 类中的成员变量可以被定义为 final 或非 final 形式。
例如,已知 JDK 的 java.lang 包下的 Math 数学类和 String 字符串类都是由 final 关键字修饰的类,这两个类就无法做任何类的父类,如果这两个类出现在 extends 右侧,就会发生编译错误,如图7.9所示。

编程训练(答案位置:资源包\TM\sl\7\编程训练)
【训练11】创建月球类 因为地球周围没有其他类似月球的卫星,所以月球类不能有子类。
【训练12】交通信号灯 编写交通类,把表示遵守交通规则的方法设为final方法,不管是行人、非机动车,还是机动车,要遵守的交通规则都是一样的。在行至有交通信号灯的路口时,要遵守“红灯停、绿灯行”的交通规则。