学习目标:掌握final常量、final方法和final类的使用。
final常量
使用final关键字修饰类内部的变量时,会限定变量的值不能被修改。通常由final修饰的变量也称为常量。例如在类中定义圆周率时,可如下声明:
final double PI=3.14;
在整个PI的应用范围内,PI的值会一直保持3.14,当有其它语句试图修改PI的值时,会导致程序编译失败,编译器也会给出错误信息。
使用final关键字修饰类内部的常量时,需要注意一下几点:
(1)被final关键字修饰的常量必须要进行初始化(给常量赋值),常量初始化有两种方式:一种是在定义常量是直接进行初始化;另一种在类的构造方法中进行初始化。
(2)如果修饰的常量是基本数据类型,常量的值不能被修改;
(3)如果修饰的常量是对象引用类型,常量会指向唯一的对象引用,该对象引用不能被修改,但对象里面的内容是可以改变的。
案例1:建立FinalVariable类,在类中声明基本数据类型的final常量。
新建项目PUnit8,在PUnit8项目新建finalvar包,在final包下新建FinalVariable类。代码如下:
package finalvar;
public class FinalVariable {
// 定义常量(圆周率),常量命名一般使用大写字母
final double PI = 3.14;
// 定义静态常量(自然常数)
static final double E = 2.71;
// 定义int类型的常量
final int radius;
public FinalVariable()
{
radius = 5;
}
}
FinalVariable类定义了两个常量PI和E,在Java语言中常量一般全部使用大写字母命名。定义了一个int类型的final常量radius(没有使用大写字母,主要是说明final关键字的用法),radius使用final关键字修饰,除了定义radius语句或构造函数语句能够对radius赋值外,其它语句都不能修改radius的值。
在finalvar包下新建测试类FinalTest1,测试FinalVariable类的final变量。代码如下:
package finalvar;
public class FinalTest1 {
public static void main(String[] args) {
// 访问静态常量
System.out.printf("%s是一个静态常量:%.2f\n","E",FinalVariable.E);
// 访问常量
FinalVariable variable = new FinalVariable();
System.out.printf("%s是一个常量:%.2f\n","PI",variable.PI);
/**
* 编译器报错,不能修改final常量的值
*/
//variable.radius = 20;
}
}
从上面的案例代码可以看出:静态常量用类名可以直接访问;基本数据类型的final常量需要实例化对象后才能访问,但不能被重新赋值。
final方法
final关键字也可以修饰类的方法,用final关键字修饰的方法,在子类中不能被重写或覆盖,但可以被重载。
案例2:新建Figure类(图形类),在Figure类提供一个draw()方法,用于绘制图形,draw()方法用final关键字修饰。然后再建立一个Figure类的子类Rectangle类,检测该类是否能够重写draw()方法。
在PUnit8项目新建figure包,在figure包下新建Figure类。代码如下:
package figure;
public class Figure {
// 定义draw()方法
public final void draw()
{
System.out.println("绘制图形");
}
}
在figure包下新建Figure类的子类Rectangle类,并重写父类的draw()方法。代码截图如下:

从Rectangle类代码截图可以看出,重写父类的draw方法时,编译器报错,错误语句是第5行,主要错误信息是要求移除Figure类draw()方法的final关键字,错误信息如下图所示。

在Rectangle类中可以尝试去掉“@Override”注解,即使去掉“@Override”注解,编译器仍然给出上面的错误信息。
由此可见,当父类的方法用final关键字修饰后,子类不能重写或覆盖父类的方法。
final类
final关键字也可以用来修饰类,用final关键字修饰的类,不能被继承并且类的内容不能被修改。
案例3:新建ErrorConstant(错误信息类),在ErrorConstant类提供常用错误信息,用于程序报错处理。ErrorConstant用final关键字修饰。然后再建立一个ErrorConstant类的子类SubErrorConstant,检测该类是否能够继承ErrorConstant类。
在PUnit8项目新建info包,在info包下新建ErrorConstant类,代码如下:
package info;
public final class ErrorConstant {
// 定义错误信息
static final String LONIN_NAME_ERROR = "登录名称错误";
static final String LONIN_PSW_ERROR = "登录密码错误";
}
ErrorConstant类定义了两个String类型的静态常量,用于表示登录名称和登录密码错误信息。
当类使用final关键字修饰后,该类不能被其它类继承。
在info包下新建测试类ErrorConstantTest,输出ErrorConstant的静态常量。代码如下:
package info;
public class ErrorConstantTest {
public static void main(String[] args) {
// 输出错误信息
System.out.println(ErrorConstant.LONIN_NAME_ERROR);
System.out.println(ErrorConstant.LONIN_PSW_ERROR);
}
}