Java中的常量变量

时间:2016-01-16 08:50:16

标签: java static instance

我正在这样的类中创建一些静态对象。我希望它们保持不变,但似乎我做错了,因为所有对象a b c是相同的(它们的x是相同的)。谁能解释为什么?

public class Key {
private Note[] sequence;
private String name;

public Key() {
    this.sequence = Note.NOTES;
}

public Key(String name, Note[] notes) {
    this.sequence = Note.NOTES;
    this.name = name;
    for(int i = 0; i < this.sequence.length; i++){
        for(int j = 0; j < notes.length; j++){
            if(this.sequence[i].equals(notes[j])){
                this.sequence[i].setIntensity(0.6);
                break;
            }
            else this.sequence[i].setIntensity((double)0);
        }
    }
}

private static final Key C = new Key("C", new Note[]{Note.F2, Note.G2, Note.A2, Note.B2, Note.C3, Note.D3, Note.E3, Note.F3, Note.G3, Note.A3, Note.B3});
private static final Key CSharp = new Key("C#", new Note[]{Note.Fsharp2, Note.Gsharp2, Note.Asharp2, Note.C3, Note.Csharp3, Note.Dsharp3, Note.F3, Note.Fsharp3, Note.Gsharp3, Note.Asharp3});
private static final Key D = new Key("D", new Note[]{Note.Fsharp2, Note.G2, Note.A2, Note.B2, Note.Csharp3, Note.D3, Note.E3, Note.Fsharp3, Note.G3, Note.A3, Note.B3});
private static final Key EFlat = new Key("Eb", new Note[]{Note.F2, Note.G2, Note.Gsharp2, Note.Asharp2, Note.C3, Note.D3, Note.Dsharp3, Note.F3, Note.G3, Note.Gsharp3, Note.Asharp3});
private static final Key E = new Key("E", new Note[]{Note.Fsharp2, Note.Gsharp2, Note.A2, Note.B2, Note.Csharp3, Note.Dsharp3, Note.E3, Note.Fsharp3, Note.Gsharp3, Note.A3, Note.B3});
private static final Key F = new Key("F", new Note[]{Note.F2, Note.G2, Note.A2, Note.Asharp2, Note.C3, Note.D3, Note.E3, Note.F3, Note.G3, Note.A3, Note.Asharp3});
private static final Key FSharp = new Key("F#", new Note[]{Note.Fsharp2, Note.Gsharp2, Note.Asharp2, Note.B2, Note.Csharp3, Note.Dsharp3, Note.F3, Note.Fsharp3, Note.Gsharp3, Note.Asharp3, Note.B3});
private static final Key G = new Key("G", new Note[]{Note.Fsharp2, Note.G2, Note.A2, Note. B2, Note.C3, Note.D3, Note.E3, Note.Fsharp3, Note.G3, Note.A3, Note.B3});
private static final Key GSharp = new Key("G#", new Note[]{Note.F2, Note.G2, Note.Gsharp2, Note.Asharp2, Note.C3, Note.Csharp3, Note.Dsharp3, Note.F3, Note.G3, Note.Gsharp3, Note.Asharp3});
private static final Key A = new Key("A", new Note[]{Note.Fsharp2, Note.Gsharp2, Note.A2, Note.B2, Note.Csharp3, Note.Dsharp3, Note.E3, Note.Fsharp3, Note.Gsharp3, Note.A3, Note.B3});
private static final Key BFlat = new Key("Bb", new Note[]{Note.F2, Note.G2, Note.A2, Note.Asharp2, Note.C3, Note.D3, Note.Dsharp3, Note.F3, Note.G3, Note.A3, Note.Asharp3});
private static final Key B = new Key("B", new Note[]{Note.Fsharp2, Note.Gsharp2, Note.Asharp2, Note.B2, Note.Csharp3, Note.Dsharp3, Note.E3, Note.Fsharp3, Note.Gsharp3, Note.Asharp3, Note.B3});
}

1 个答案:

答案 0 :(得分:0)

您的代码使用不同的值创建不同的对象,但它们不是常量

要创建常量,您需要将变量声明为 final ,此外,您需要阻止更改它的任何可能性,使对象不可变。在这种情况下,可以将 final所有字段完成。 更一般地说,要创建一个不可变类,您需要遵循一些规则:

  • 不要添加任何setter方法

  • 声明所有字段为final和private

  • 如果某个字段是可变对象,则为getter方法创建它的防御性副本

  • 如果必须将传递给构造函数的可变对象分配给某个字段,请创建一个防御性副本

  • 不允许子类覆盖方法。

如果您想了解一些关于不可变对象的其他信息,我在DZone上写了一篇文章,你可以在下面找到link

所以对于你的代码:

final Class A {
    final int x;

    public A(int x) {
        this.x = x;
    };

    private final static A a = new A(1);
    private final static A b = new A(2);
    private final static A c = new A(3);
}

回答最后的评论。

在你的构造函数中,你有:

public Key(String name, Note[] notes) {
    this.sequence = Note.NOTES;
    ...
}

这意味着sequence的值对Key的所有实例都是通用的。如果你需要不同的序列值,你需要做类似的事情(基本上克隆数组Note.NOTES)

public Key(String name, Note[] notes) {
    this.sequence = Note.NOTES.clone();
    ...
}