首页 > 编程笔记 > Java笔记 阅读:16

Java final关键字的用法(非常详细,附带实例)

final 是 Java 中的一个重要的关键字,可以修饰变量(成员变量或局部变量)、方法以及类:

Java final修饰变量

1) final修饰局部变量

使用 final 关键字修饰的局部变量,只能被赋值一次。如果再次对该局部变量进行赋值,则程序在编译时会报错。

举个简单的例子:
public class Demo {
    public static void main(String[] args) {
        final String JAVA_VERSION = "15.0.1";
        JAVA_VERSION = "17.0.1";
        System.out.println("当前JAVA版本号:" + JAVA_VERSION);
    }
}
程序编译报错,提示“Cannot assign a value to final variable 'JAVA_VERSION'”,中文含义为“无法为最终变量 JAVA_VERSION 分配值”,出现错误的原因是,final 修饰的变量为常量,只能初始化一次,初始化后不能再修改。

第 3 行代码将当前 Java 版本号 15.0.1 赋值给了常量字符串 JAVA_VERSION,因此第 4 号代码再次赋值时会编译报错。将第 3 行代码修改如下:
final String JAVA_VERSION;
程序的运行结果如下:

当前JAVA版本号:17.0.1

再次运行程序可以发现,第 3 行代码的常量 JAVA_VERSION 只做声明,在第 4 行代码赋值一次,程序运行不会报错。

2) final修饰成员变量

对于成员变量来说,一旦使用 final 关键字修饰,也是一样不能改变。

和 final 修饰局部变量的不同点是,final 修饰的成员变量必须声明的时候赋值或者在构造方法中对其赋值,但是只能二者选一,如果没有直接赋值,那就必须保证所有重载的构造方法最终都会对 final 修饰的成员变量进行赋值。

接下来,通过案例来演示使用 final 修饰成员变量:
class Father {
    final int CODE; // 使用final修饰成员变量

    public void show() {
        System.out.println("当前常量代码CODE为:" + this.CODE);
    }
}

public class Demo {
    public static void main(String[] args) { // 创建Father对象
        Father f = new Father();
        f.show();
    }
}
程序编译报错,提示“Variable 'CODE' might not have been initialized”,中文含义为“变量 CODE 未在默认构造器中初始化”,出现错误的原因是,Java 虚拟机不会为 final 修饰的成员变量默认初始化。

因此,使用 final 修饰成员变量时,需要在声明时进行赋值,或者在构造方法中进行初始化。可以修改第 2 行代码如下:
final int CODE= 1024;
或者修改 Father 类的代码如下:
class Father {
    final int CODE; // 使用final修饰成员变量
    String name;
    Father() {
        CODE = 1024;
    }
    Father(String n, int code) {
        name = n;
        CODE = code;
    }
    public void show() {
        System.out.println("当前常量代码CODE为:" + this.CODE);
    }
}

// 需要添加一个主类来运行程序
public class Demo {
    public static void main(String[] args) {
        Father f1 = new Father();
        f1.show();
       
        Father f2 = new Father("John", 2048);
        f2.show();
    }
}
两种修改方式均可,运行程序之后的结果如下:

当前常量代码CODE为:1024

注意,对于父类中使用 final 修饰的成员变量,子类是可以继承的,但不能修改该成员变量的值。

Java final修饰成员方法

使用 final 关键字修饰的成员方法,表示子类不能重写此方法,称为最终方法。对于一些比较重要且不希望被子类重写的成员方法,可以使用 final 关键字对其进行修饰。

接下来,通过案例来演示使用 final 修饰成员方法。
class Father {
    public final void show() {
        System.out.println("final修饰show()方法");
    }
}

class Son extends Father {
    public void show() { // 重写父类show()方法
        System.out.println("重写父类show()方法");
    }
}

public class Demo {
    public static void main(String[] args) { // 创建Father类对象
        Father f = new Father();
        f.show();
    }
}
程序编译报错,提示“'show()' cannot override 'show()' in 'xxx.Father'; overridden method is final”,中文含义为“show()无法覆盖 xxx.Father 中的 show(),被覆盖的方法为 final”,出现错误的原因是,被 final 修饰的成员方法不能再被子类重写。

当一个常数或方法需要在程序里反复使用的时候,我们就可以把它定义为 static final,这样内存就不用重复地申请和释放空间。用 static final 来修饰的成员变量或成员方法,可理解为“全局常量”或“全局方法”。

Java final修饰类

如果一个类被 final 所修饰,则说明这个类不能被其他类所继承,即该类不可能有子类,这种类被称为最终类。

接下来,通过案例来演示使用 final 修饰类。
final class Father {
}

class Son extends Father { // 编译报错
}

public class Demo {
    public static void main(String[] args) { // 创建Son对象
        Son s = new Son();
    }
}
程序编译报错,提示“'Cannot inherit from final 'xxx.Father'”,中文含义为“无法从最终类 xxx.Father 进行继承”,出现错误的原因是,被 final 所修饰的类为最终类,不能被子类继承。

注意,所有已被 private 修饰的私有方法以及所有包含在 final 类中的方法,都默认是最终方法。

相关文章