Java 中的 final 关键字有三个作用,分别如下。
如果使用 final 关键字修饰基本数据类型的变量,则该变量为常量,变量的值无法修改。
如果使用 final 关键字修饰引用数据类型的变量(比如对象、数组等),则变量中存储的对象地址是不能改变的。但是,可以修改变量指向的对象本身中的内容。
如果使用 final 关键字修饰类的成员变量,则必须立即赋值(注意:),否则编译会报错。
示例:
import java.util.Arrays; public class Demo { // 正确,因为立即被初始化 private final int a = 10; // 正确,它在构造方法中被初始化了 private final int b; // 正确:在实例代码块中初始化 private final int c; // 正确:静态变量,在静态块中初始化 private static final int d; // 错误:变量没有初始化 //private static final int e; //private final int f; // 静态代码块 static { // 初始化 d d = 10; } // 实例代码块 { // 初始化 c c = 10; } // 构造方法 public Demo() { // 初始化变量 b b = 10; } public static void main(String[] args) { // 正确,立即初始化 final int val = 100; System.out.println("val=" + val); // 正确,紧接着初始化 final int val2; val2 = 100; System.out.println("val2=" + val2); // 错误:不能给 final 变量重新赋值 //val = 200; final int[] valArray = new int[10]; System.out.println(Arrays.toString(valArray)); // 错误:不能给 final 变量重新赋值 //valArray = new int[20]; // 修改变量指向对象的内容 valArray[0] = 10; valArray[1] = 20; System.out.println(Arrays.toString(valArray)); } }
运行示例,输出结果如下:
val=100 val2=100 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [10, 20, 0, 0, 0, 0, 0, 0, 0, 0]
当使用 final 关键字修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。
示例:
public class Demo { class A { // 声明了一个最终方法,该方法不能被子类重写 public final void show(String msg) { System.out.println(msg); } } class B extends A { // 错误:因为父类的 show() 方法是 final 的,不能被子类重写 /*public final void show(String msg) { System.out.println(msg); }*/ } public static void main(String[] args) { Demo demo = new Demo(); A a = demo.new A(); a.show("hello A.java"); B b = demo.new B(); b.show("hello B.java"); } }
运行示例,输出结果如下:
hello A.java hello B.java
当用 final 关键字修改类时,该类成为最终类,无法被继承。简称为“断子绝孙类”。
示例:
public class Demo { final class A { // 声明了一个最终方法,该方法不能被子类重写 public void show(String msg) { System.out.println(msg); } } // 错误:A 类是最终类,不能被继承 // class B extends A {} public static void main(String[] args) { Demo demo = new Demo(); A a = demo.new A(); a.show("hello A.java"); } }
运行示例,输出结果如下:
hello A.java