Dies ist eine Entwurfsauswahl von Java Enums, die das Ändern der Ordinalwerte nicht unterstützt. Grundsätzlich sind sie nicht stabil genug, um von ihnen abhängig zu sein. Wenn Sie die Position von B und C in Ihrem Beispiel ändern, werden die Clients abhängig von den Ordinalwerten gebrochen. Dies kann unbeabsichtigt passieren.
Das Problem wird in Effektiv Java Item 31: Use instance field instead of ordinals beschrieben.
Sie können das Verhalten in einer stabilen Weise emulieren:
enum X{
A(10), B(A), C(B), D(5000), E(D), F(E);
private final int value;
X(int value){
this.value = value;
}
X(X preceding){
this.value = preceding.getValue() + 1;
}
public int getValue() {
return value;
}
@Override
public String toString() {
return this.name() + "(" + this.value + ")";
}
static {
Set<Integer> values = new HashSet<Integer>();
for(X x : X.values()) values.add(x.value);
assert(values.size() == X.values().length); //no duplicates
}
}
Mit dieser Definition der Reihenfolge der Werte, die Sie können, ohne Kunden zu brechen ändern.
Aufruf for(X x : X.values()) System.out.println(x);
Rückkehr:
A(10)
B(11)
C(12)
D(5000)
E(5001)
F(5002)
'Es ist hier, damit Sie zeigen können und laugh.' Haha. Gute! –
Der Standardkonstruktor muss Counter.nextValue aktualisieren, und Sie können den nextValue wahrscheinlich auch direkt in Foo entfernen. – Yuliy
@Yuliy: Der parameterlose Konstruktor ruft den parametrisierten Konstruktor auf, so dass Counter.nextValue aktualisiert wird. Den nextValue direkt in Foo * zu setzen funktioniert nicht - zumindest nicht mit der Version von javac, die ich benutze. Es verhindert, dass Sie auf statische Felder im Konstruktor zugreifen. –