Java 之 final 关键字

在 Java 中,有三种情况可能使用到 final:数据、方法和类。

1. final 数据

对于基本类型,final 使数值恒定不变;对于对象引用,final 使其引用不变,但是引用指向的对象本身可以被修改,数组也是对象。

public class finalData {
    private static final int VAL_1 = 1;
    private final Value value_1 = new Value(2);
    private final int a[] = {1, 2, 3, 4};

    public static void main(String[] args) {
        finalData finalData = new finalData();
       // finalData.VAL_1 = 2;  // error:Cannot assign a value to final variable 'VAL_1'
       // finalData.value_1 = new Value(3);  // error:Cannot assign a value to final variable 'value_1'
        finalData.value_1.i++;
       // finalData.a = new int[3];  //error:Cannot assign a value to final variable 'a'
        for (int i = 0; i < finalData.a.length; i++) {
            finalData.a[i]++;
        }
    }
}
class Value {
    int i;
    public Value(int i) {
        this.i = i;
    }
}

可以看到,虽然引用 value_1 不能改变,但是其成员 i 是可以改变的,数组 a 同理。

空白 final

空白 final 是指被声明为 final 但又未给定初值的域。但是无论什么情况,编译器都会确保空白 final 在使用前被初始化,否则会提示未初始化变量。

final 参数

将参数指明为 final 时,意味着无法在方法中更改参数引用所指向的对象。

public class FinalArguments {
    void without(Gizmo g){
        g = new Gizmo();
        g.spin();
    }

    void with(final Gizmo g){
//        g = new Gizmo();   // Error,g 被定义为 final
    }

    void g(final int i){
//        i++;     // Error,i 被定义为 final
    }
    int f(final int i){
        return i+1;
    }

    public static void main(String[] args) {
        FinalArguments fa = new FinalArguments();
        Gizmo gizmo = new Gizmo();
        fa.with(gizmo);
        fa.without(gizmo);
    }

}
class Gizmo{
    public void spin(){}
}

2. final 方法

使用 final 方法可以把方法锁定,防止任何继承类修改它的定义。
类中所有的 private 方法都隐式地指定为 final 的,继承类无法取到 private 方法,当然也无法覆盖它,所以为 private 方法添加 final 修饰词毫无意义。

class WithFinals {
    private final void f(){
        System.out.println("WithFinals.f()");
    }
    private void g(){
        System.out.println("WithFinals.g()");
    }
}
class OverridingPrivate extends WithFinals{
    // 虽然此时 OverridingPrivate 继承了 WithFinals 类,但是这并不是重写的父类方法,只是名字相同而已
    private final void f(){
        System.out.println("OverridingPrivate.f()");
    }
    private void g(){
        System.out.println("OverridingPrivate.g()");
    }

    public static void main(String[] args) {
        OverridingPrivate op = new OverridingPrivate();
        op.f();
        op.g();
        WithFinals wf = op;
//        wf.f();  子类对象无法调用父类对象的私有方法
//        wf.g();   子类对象无法调用父类对象的私有方法
    }
}

3. final 类

当使用 final 修饰类时,表明该类无法被继承。
由于 final 类禁止继承,所以 final 类中所有方法隐式指定为 final 的,因为无法覆盖它们。

final class Dinosaur {
    int i = 1;
}
// class Further extends Dinosaur{}  // Error:Cannot inherit from final 'Dinosaur'

总结

被 final 修饰的数据/方法/类无法被改变

  1. final 修饰基本类型时,该数据被初始化一次后无法改变,当 final 修饰引用类型时,该引用不可变,但是引用指向的对象本身可变。
  2. final 修饰方法时,该方法无法被重写
  3. final 修饰类时,该类无法被继承
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值