final 变量是否随时间改变其值?

问题描述

我目前正在通过教科书自学 Java,发现了一段我不明白的代码 - 为什么最终变量 id 会改变它的值?

import static net.mindview.util.Print.*;
class Shared {
    private int refcount = 0;
    private static int counter = 0;
    private final int id = counter++;
    public Shared() {
        print("Creating " + this);
    }
    public void addRef() { refcount++; }
    protected void dispose() {
        if(--refcount == 0)
            print("disposing " + this);
    }
    protected void finalize() {
        if(refcount != 0)
            print("Error: object is not properly cleaned-up!");
    }
    public String toString() { return "Shared " + id; }
}
class Composing {
    private Shared shared;
    private static int counter = 0;
    private final int id = counter++;
    public Composing(Shared shared) {
        print("Creating " + this);
        this.shared = shared;
        this.shared.addRef();
    }
    protected void dispose() {
        print("disposing " + this);
        shared.dispose();
    }
    public String toString() { return "Composing " + id; }
}
public class E13_VerifiedRefCounting {
    public static void main(String[] args) {
        Shared shared = new Shared();
        Composing[] composing = { new Composing(shared),new Composing(shared),new Composing(shared) };
        for(Composing c : composing)
            c.dispose();

解决方法

这个:

    private static int counter = 0;
    private final int id = counter++;
    public Shared() {
        print("Creating " + this);
    }

与此相同:

    private static int counter = 0;
    private final int id;
    public Shared() {
        id = counter++;
        print("Creating " + this);
    }

也就是说,每次构造函数执行时都会分配 id,副作用是 counter 递增。

id 是一个实例变量,因此 shared 的每个实例都有自己的 id 值。

,
private final int id = counter++;

如果你问为什么 id 的值是 counter + 1 而不是 counter,那是因为首先计算总和 counter + 1,然后它设置为 id。之后,id 的值将无法更改。