我正在尝试将一些C ++代码翻译成Java。我正在寻找在Java中模拟这种类型的C ++范例的最佳方法 - 我认为枚举可能是答案,但我对任何事情持开放态度
C ++代码:
typedef UInt32 Type;
enum { UNKNOWN, QUIT, SYSTEM, TIMER, LAST }
...
Type newType = UNKNOWN;
Type nextType = LAST + 1;
...
// "Register" the new type
newType = nextType;
nextType++;
...
switch (newType) {
case UNKNOWN:
case QUIT:
...
case LAST:
// Ignore unset or predefined types
default:
// Some type other than the predefined. Do something special
基本上我正在寻找一种“扩展”Java枚举值的方法。
enum Type { UNKNOWN, QUIT, SYSTEM, TIMER, LAST }
不会退出它。
我喜欢为强类型创建一个新对象的想法。
同样,我正在寻找在这里使用的最佳模式。我可以轻松地通过一些公共静态最终int UNKNOWN等来漂浮
答案 0 :(得分:3)
Java枚举的一个优点是,它们本质上就像所有其他对象一样。特别是,您可以在常量上使用方法,并使您的枚举实现接口:
interface Useful {
void doStuff();
}
enum Foo implements Useful {
DEFAULT {
public void doStuff() {
...
}
},
MAGIC {
public void doStuff() {
...
}
}
}
因此,您的方法不是接受枚举类型的参数,而是接受接口的任何实现,特别是通过让枚举常量实现任何必要的实现来提供默认的东西。
他们也可以有成员:
enum Explicit {
FIRST(0), SECOND(1), THIRD(2);
private final int value;
private Explicit(int v) {
this.value = v;
}
}
注意,常量有一个内部数值(反映其对等体中常量的位置),可以使用ordinal
方法访问:
assert Explicit.FIRST.ordinal() == 0;
但依靠这一点有点危险。如果你打算(比如说)在数据库中保存枚举常量,那么以下更改将破坏代码:
enum Explicit {
FIRST(0), NEWELT(-1), SECOND(1), THIRD(2);
private final int value;
private Explicit(int v) {
this.value = v;
}
}
使用序数值时。因此,序列化机制在序列化枚举值时使用常量名称而不是其位置。
所以:
Type.X + 1
将是
Enum.values()[Enum.X.ordinal() + 1]
并且交换机可以使用枚举本身实现的接口建模(您可以在Java中使用switch语句中的枚举,但通常,使枚举实现必要的代码会产生更易维护的代码)
答案 1 :(得分:2)
如果Type的每个值只是一个int,那么我可能会在类中找到一堆静态最终的int。
只是为了记录,这样的东西或多或少类型安全。如果不了解更多问题,我无法确定复杂性是否合理。
public class abstract Type
{
public static final Type UNKNOWN = registerStd("UNKNOWN");
...
public static final Type TIMER = registerStd("TIMER");
// use this to keep track of all the types
private static final List<Type> REGISTERED = ...
//This will do your switch statement for you, implemented by
// anonymous subclasses
public abstract void dispatch(Type onMe);
// here's how you make the standard ones
private static Type registerStd(String name)
{
Type heresOne = new Type(name)
{
// note, it's a no-op
public void dispatch(DoStuffer algorithm) {}
};
REGISTERED.add(heresOne);
return heresOne;
}
//here's how you make the non-standard ones
public static Type registerNew(String name)
{
Type heresOne = new Type(name)
{
public void dispatch(DoStuffer algorithm) {algorithm.execute(this)}
};
REGISTERED.add(heresOne);
return heresOne;
}
}
public interface DoStuffer
{
public void execute(Type onMe);
}
//Then your code becomes
Type newType = Type.registerNew("NewType");
newType.dispatch
(
new DoStuffer()
{
public void algorithm(Type forMe) { ... }
}
);
也许这有点深奥。但它确实允许在调用者站点“易于调度”和在某种意义上的可扩展枚举。