Java final的3种用法(附带实例)
final 被译为“最后的”“最终的”,final 是 Java 语言中的一个关键字,凡是被 final 关键字修饰过的内容都是不可改变的。本节将讲解 final 关键字的 3 种使用场景。
例如,在类中定义 PI 值,可以使用如下语句:
注意,由 final 关键字定义的变量必须在声明时对其进行赋值操作,并且编译器不允许在程序中再次对定义为 final 的常量进行赋值。
final 关键字除了可以修饰基本数据类型的常量,还可以修饰对象引用。由于数组也可以被看作一个对象来引用,因此 final 关键字可以修饰数组。
一个对象引用一旦被修饰为 final 关键字后,它就只能恒定指向一个对象,无法将其改变以指向另一个对象。一个既是 static 又是 final 的字段只占据一段不能改变的存储空间。
【实例】创建 FinalData 类,在该类中定义表示圆周率的常量 PI,并尝试修改 PI 的值。

图 1 修改final的常量时发生的编译错误
我们学习 Java 修饰权限中的 private 修饰符,如果一个父类的某个方法被设置为 private,子类将无法访问该方法,自然无法覆盖该方法。也就是说,一个定义为 private 的方法被隐式地指定为 final 类型,因此无须将一个定义为 private 的方法再定义为 final 类型。例如下面的语句:
【实例】使用 final 关键字为电视机上儿童锁。创建 Dad 爸爸类,给 Dad 类定义一个打开电视机的方法,该方法使用 final 关键字修饰。创建 Dad 类的子类 Baby 类,让 Baby 类尝试自己重写打开电视的方法。

图 2 final方法无法被重写
因为打开电视这个方法是由 final 关键字修饰的,子类无法被重写。所以 Baby 想要打开电视,就只能找爸爸来打开了。
final 类的语法如下:
例如,已知 JDK 的 java.lang 包下的 Math 数学类和 String 字符串类都是由 final 关键字修饰的类,这两个类就无法做任何类的父类,如果这两个类出现在 extends 右侧,就会发生编译错误,如下图所示。

图 3 final类无法被继承
Java final变量
final 关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。通常,由 final 关键字定义的变量为常量。例如,在类中定义 PI 值,可以使用如下语句:
final double PI = 3.14;当在程序中使用了 PI 这个常量时,它的值就是 3.14。
注意,由 final 关键字定义的变量必须在声明时对其进行赋值操作,并且编译器不允许在程序中再次对定义为 final 的常量进行赋值。
final 关键字除了可以修饰基本数据类型的常量,还可以修饰对象引用。由于数组也可以被看作一个对象来引用,因此 final 关键字可以修饰数组。
一个对象引用一旦被修饰为 final 关键字后,它就只能恒定指向一个对象,无法将其改变以指向另一个对象。一个既是 static 又是 final 的字段只占据一段不能改变的存储空间。
【实例】创建 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 就会报出如下图所示的编译错误,常量 PI 不允许被修改。

图 1 修改final的常量时发生的编译错误
Java final方法
将方法定义为 final 类型,可以防止子类修改父类的定义与实现方式,同时定义为 final 的方法的执行效率要高于非 final 方法。我们学习 Java 修饰权限中的 private 修饰符,如果一个父类的某个方法被设置为 private,子类将无法访问该方法,自然无法覆盖该方法。也就是说,一个定义为 private 的方法被隐式地指定为 final 类型,因此无须将一个定义为 private 的方法再定义为 final 类型。例如下面的语句:
private final void test(){ ... //省略一些程序代码 }
【实例】使用 final 关键字为电视机上儿童锁。创建 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 就会报出如下图所示的编译错误:

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

图 3 final类无法被继承