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