总览
Java中的枚举比许多其他语言更强大,这可能导致令人惊讶的用途。
在本文中,我概述了Java 枚举的一些单独功能,并将它们组合在一起形成一个状态机。
单例和实用程序类的枚举
您可以非常简单地将枚举用作Singleton或Utility。
enum Singleton {
INSTANCE;
}
enum Utility {
; // no instances
}
枚举实现一个接口
您还可以在枚举中实现接口。
interface Named {
public String name();
public int order();
}
enum Planets implements Named {
Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune;
// name() is implemented automagically.
public int order() { return ordinal()+1; }
}
每个枚举实例都有一个不同的子类
您可以覆盖实例的行为。 这有效地为实例提供了具有自己实现的枚举的另一个子类。
// from http://download.oracle.com/javase/1,5.0/docs/guide/language/enums.html
public enum Operation {
PLUS { double eval(double x, double y) { return x + y; } },
MINUS { double eval(double x, double y) { return x - y; } },
TIMES { double eval(double x, double y) { return x * y; } },
DIVIDE { double eval(double x, double y) { return x / y; } };
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
}
使用枚举作为状态机
您可以使用所有这些技术来创建基于枚举的语句。
在这个简短的示例中,解析器状态机处理ByteBuffer中的原始XML。 每个状态都有其自己的处理方法,如果没有足够的可用数据,则状态机可以返回以检索更多数据。 状态之间的每个过渡都定义明确,所有状态的代码都放在一个枚举中 。
interface Context {
ByteBuffer buffer();
State state();
void state(State state);
}
interface State {
/**
* @return true to keep processing, false to read more data.
*/
boolean process(Context context);
}
enum States implements State {
XML {
public boolean process(Context context) {
if (context.buffer().remaining() < 16) return false;
// read header
if(headerComplete)
context.state(States.ROOT);
return true;
}
}, ROOT {
public boolean process(Context context) {
if (context.buffer().remaining() < 8) return false;
// read root tag
if(rootComplete)
context.state(States.IN_ROOT);
return true;
}
}
}
public void process(Context context) {
socket.read(context.buffer());
while(context.state().process(context));
}
使用这种方法,可以编写一个XML解析器,该解析器可以在不到10微秒的时间内处理数据包。 它是大多数情况下所需的效率。
参考: Java秘密:使用我们的JCG合作伙伴 Peter Lawrey在Vanilla Java上 使用枚举来构建状态机 。
相关文章:
翻译自: https://www.javacodegeeks.com/2011/07/java-secret-using-enum-to-build-state.html