Dieser Eintrag befasst sich mit der Definition abstrakter Methoden in der Java-Enumeration und dem Schreiben ihres Verhaltens. (Die in Effective Java 3rd Edition geschriebene Version ist fast dieselbe. Notieren Sie sich, was Sie versucht haben.)
Mit Java Enum können Sie sowohl Methoden als auch Werte definieren.
Muster, das nur den Wert definiert
enum Operator {
PLUS, SUBTRACT, MULTIPLY, DIVIDE, NONE
}
Auf der anderen Seite können Sie für jeden Wert eine Methode definieren und wie in der folgenden Abbildung gezeigt schreiben.
enum Operator {
PLUS {
@Override
BigDecimal apply(@NonNull BigDecimal lhs, @NonNull BigDecimal rhs) {
return lhs.add(rhs);
}
},
SUBTRACT{
@Override
BigDecimal apply(@NonNull BigDecimal lhs, @NonNull BigDecimal rhs) {
return lhs.subtract(rhs);
}
},
MULTIPLY {
@Override
BigDecimal apply(@NonNull BigDecimal lhs, @NonNull BigDecimal rhs) {
return lhs.multiply(rhs);
}
},
DIVIDE {
@Override
BigDecimal apply(@NonNull BigDecimal lhs, @NonNull BigDecimal rhs) {
return lhs.divide(rhs, BigDecimal.ROUND_UNNECESSARY);//;
}
},
NONE {
// allow null for rhs
@Override
BigDecimal apply(@NonNull BigDecimal lhs, BigDecimal rhs) {
return lhs;
}
};
abstract BigDecimal apply(BigDecimal lhs, BigDecimal rhs);
}
In "abstract BigDecimal apply (BigDecimal lhs, BigDecimal rhs);" in enum wird die für alle Werte zu definierende Methode angegeben und die Methode wird überschrieben, wenn jeder Wert deklariert wird.
(Ergänzung) In der obigen Quelle ist "@NonNull" eine der von lombok bereitgestellten Anmerkungen, die die Nullprüfung implementiert. ist.
Wenn Sie in der obigen Form enum definieren, verwenden Sie beispielsweise die folgende Methode
public synchronized BigDecimal pushEvalButton() {
var v = new BigDecimal(sb.toString());
switch(currentOperator) {
case PLUS: {
v = stack.add(getCurrentValue());
break;
}
case SUBTRACT: {
v = stack.subtract(getCurrentValue());
break;
}
case MULTIPLY: {
v = stack.multiply(getCurrentValue());
break;
}
case DIVIDE: {
v = stack.divide(getCurrentValue(), BigDecimal.ROUND_UNNECESSARY);//
break;
}
case NONE: {
return v;
}
default: {
throw new RuntimeException("Not defined.");
}
}
currentOperator = Operator.NONE;
replaceBuffer(v.toPlainString());
clearStack();
return v;
}
Sie können wie folgt klar schreiben.
public synchronized BigDecimal pushEvalButton() {
var v = new BigDecimal(sb.toString());
if(Operator.NONE == currentOperator) {
return v;
}
v = currentOperator.apply(stack, getCurrentValue());
currentOperator = Operator.NONE;
replaceBuffer(v.toPlainString());
clearStack();
return v;
}
Da der Inhalt auf die Enum-Methode verschoben wurde, ist es natürlich, dass der Code von der ursprünglichen Methode reduziert wird, aber ich hatte das Gefühl, dass das Folgende Verdienste sind.
In diesem Eintrag habe ich ein Beispiel für das Definieren abstrakter Methoden in einer Java-Enumeration und das Schreiben ihres Verhaltens gezeigt.
Ein Beispiel für die oben genannten Unterschiede finden Sie unter [Dieses Commit] auf GitHub (https://github.com/hrkt/commandline-calculator/commit/47e7b05075c2bb632b9bdabdf044ab3b5cefdeee).
Recommended Posts