我正在这样的类中创建一些静态对象。我希望它们保持不变,但似乎我做错了,因为所有对象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});
}
答案 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();
...
}