(五)《Java编程思想》——final关键字

可能使用final的三种情况:数据、方法、类。

1.final数据

final 常量必须是基本类型数据,且在定义时须赋值;

一个既是static又是final的域只占据一段不能改变的存储空间,只有一份;(使用全大写字母命名)

当用于对象引用,final使引用只能指向一个对象(实例化一次)。对象本身可以修改。

package chapter7;

import java.util.Random;

/**
 * final数据
 */
class Value {
    int i;

    public Value(int i) {
        this.i = i;
    }
}

public class FinalData {
    private static Random rand = new Random(47);
    private String id;

    public FinalData(String id) {
        this.id = id;
    }

    private final int valueOne = 9;
    private static final int VALUE_TWO = 99;
    public static final int VALUE_THREE = 39;

    private final int i4 = rand.nextInt(20);
    static final int INT_5 = rand.nextInt(20);

    private Value v1 = new Value(11);
    private final Value v2 = new Value(22);
    private static final Value VAL_3 = new Value(33);

    private final int[] a = { 1, 2, 3, 4, 5, 6 };

    public String toString() {
        return id + ": " + "i4 = " + i4 + ",INT_5 = " + INT_5;
    }

    public static void main(String[] args) {
        FinalData fd1 = new FinalData("fd1");
        // fd1.valueOne++;
        fd1.v2.i++;
        fd1.v1 = new Value(9);
        for (int i = 0; i < fd1.a.length; i++)
            fd1.a[i]++;
        // !fd1.v2=new Value(0);
        // !fd1.VAL_3=new Value(1);
        // !fd1.a=new int[3];
        System.out.println(fd1);
        System.out.println("Creating new FinalData");
        FinalData fd2 = new FinalData("fd2");
        System.out.println(fd2);
    }
}

【运行结果】:
fd1: i4 = 15,INT_5 = 18
Creating new FinalData
fd2: i4 = 13,INT_5 = 18

final与static final的区别是:final在一个对象类唯一,static final在多个对象中都唯一。

空白final

需在构造函数中对final赋值

package chapter7;

import java.awt.PageAttributes;

/**
 * 空白final
 */
class Poppet {
    private int i;

    Poppet(int ii) {
        i = ii;
    }
}

public class BlankFinal {
    private final int i = 0;
    private final int j;
    private final Poppet p;

    public BlankFinal() {
        j = 1;
        p = new Poppet(1);
    }

    public BlankFinal(int x) {
        j = x;
        p = new Poppet(x);
    }

    public static void main(String[] args) {
        new BlankFinal();
        new BlankFinal(47);
    }
}

final方法

要明确禁止覆盖时,才将方法设置为final;

若基类中方法为private时,该方法不是接口的一部分,仅是隐藏于类中的代码。

下面的例子证明,基类中方法为private,导出类中以相同名称生成public等方法,并没有覆盖基类中的方法。

package chapter7;

class WithFinal {
    private final void f() {
        System.out.println("WithFinal f()");
    }

    private final void g() {
        System.out.println("WithFinal g()");
    }
}

class OverridingPrivate extends WithFinal {
    private final void f() {
        System.out.println("OverridingPrivate f()");
    }

    private final void g() {
        System.out.println("OverridingPrivate g()");
    }
}

class OverridingPrivate2 extends OverridingPrivate {
    public final void f() {
        System.out.println("OverridingPrivate2 f()");
    }

    public final void g() {
        System.out.println("OverridingPrivate2 g()");
    }
}

public class FinalOverridIllusion {
    public static void main(String[] args) {
        OverridingPrivate2 op2 = new OverridingPrivate2();
        op2.f();
        op2.g();
        OverridingPrivate op = op2;
        // !op.f();
        // !o2.g();
        WithFinal wf = op2;
        // !wf.f();
        // !wf.g();
    }
}

【运行结果】:
OverridingPrivate2 f()
OverridingPrivate2 g()

final类

不能继承该类

原文地址:https://www.cnblogs.com/echolxl/p/3205530.html