是否有任何理由覆盖 Java 8 中枚举中的方法
Is there any reason to override methods in enums in Java 8
正如所指出的 here lambda 提供了一种非常优雅的方式来指定单个枚举值的行为。
在 Java 8 之前,我通常会将其实现为:
enum Operator {
TIMES {
public int operate(int n1, int n2) {
return n1 * n2;
}
},
PLUS {
public int operate(int n1, int n2) {
return n1 + n2;
}
};
public int operate(int n1, int n2) {
throw new AssertionError();
}
}
现在我倾向于使用:
enum Operator {
TIMES((n1, n2) -> n1 * n2),
PLUS((n1, n2) -> n1 + n2);
private final BinaryOperator<Integer> operation;
private Operator(BinaryOperator<Integer> operation) {
this.operation = operation;
}
public int operate(int n1, int n2) {
return operation.apply(n1, n2);
}
}
这看起来更优雅。
我现在想不出为特定枚举值重写方法的理由。所以我的问题是,现在是否有充分的理由在 enum
中使用方法覆盖,或者应该始终首选功能接口?
如果您查看 this answer,其中总结了在此 enum
场景中使用 lambda 表达式的优势,您可能会注意到这些优势在 Java 8 之前的变体中都消失了。它既不比旧的专用 enum
变体更具可读性,也没有提高性能。此外,interface BinaryOperator
在 Java 8 之前不存在,所以它是另一个 class 您需要添加到您的代码库以遵循此方法。
如果您打算很快切换到 Java 8,那么在 Java 8 之前的代码中使用这种委托方法的主要原因是为了简化迁移。
更新您的问题:
如果您主要关注 Java 8 用例,我建议在所有 enum
个案例都有不同的行为时始终使用委托方法,这些行为仍然遵循可以受益的相似模式使用 lambda 表达式,就像在您的示例中实现运算符时的情况一样。
一个反例是 enum
,其中大多数都有一个共同的行为,只有在一种或少数情况下才会被覆盖。例如:
enum Tokens {
FOO, BAR, BAZ, AND, A, LOT, MORE // etc …
/** Special Token End-Of-File */
EOF {
@Override
public boolean matches(String input, int pos) {
return input.length()==pos;
}
};
// all ordinary tokens have the same behavior
public boolean matches(String input, int pos) {
return input.length()-pos >= name().length()
&& input.regionMatches(pos, name(), 0, name().length());
}
}
正如所指出的 here lambda 提供了一种非常优雅的方式来指定单个枚举值的行为。
在 Java 8 之前,我通常会将其实现为:
enum Operator {
TIMES {
public int operate(int n1, int n2) {
return n1 * n2;
}
},
PLUS {
public int operate(int n1, int n2) {
return n1 + n2;
}
};
public int operate(int n1, int n2) {
throw new AssertionError();
}
}
现在我倾向于使用:
enum Operator {
TIMES((n1, n2) -> n1 * n2),
PLUS((n1, n2) -> n1 + n2);
private final BinaryOperator<Integer> operation;
private Operator(BinaryOperator<Integer> operation) {
this.operation = operation;
}
public int operate(int n1, int n2) {
return operation.apply(n1, n2);
}
}
这看起来更优雅。
我现在想不出为特定枚举值重写方法的理由。所以我的问题是,现在是否有充分的理由在 enum
中使用方法覆盖,或者应该始终首选功能接口?
如果您查看 this answer,其中总结了在此 enum
场景中使用 lambda 表达式的优势,您可能会注意到这些优势在 Java 8 之前的变体中都消失了。它既不比旧的专用 enum
变体更具可读性,也没有提高性能。此外,interface BinaryOperator
在 Java 8 之前不存在,所以它是另一个 class 您需要添加到您的代码库以遵循此方法。
如果您打算很快切换到 Java 8,那么在 Java 8 之前的代码中使用这种委托方法的主要原因是为了简化迁移。
更新您的问题:
如果您主要关注 Java 8 用例,我建议在所有 enum
个案例都有不同的行为时始终使用委托方法,这些行为仍然遵循可以受益的相似模式使用 lambda 表达式,就像在您的示例中实现运算符时的情况一样。
一个反例是 enum
,其中大多数都有一个共同的行为,只有在一种或少数情况下才会被覆盖。例如:
enum Tokens {
FOO, BAR, BAZ, AND, A, LOT, MORE // etc …
/** Special Token End-Of-File */
EOF {
@Override
public boolean matches(String input, int pos) {
return input.length()==pos;
}
};
// all ordinary tokens have the same behavior
public boolean matches(String input, int pos) {
return input.length()-pos >= name().length()
&& input.regionMatches(pos, name(), 0, name().length());
}
}