是否可以在java中定义类似的内容?
C#代码:
public enum Character
{
A = 1,
B = 2,
C = 4,
D = 8
}
...
Character ch = /* from user */
if(ch & Character.A)
{
// some operation...
}
例如,如果ch
设置为Character.B
,那么if
的结果将为false
:
ch = 00000000 00000000 00000000 00000010
A = 00000000 00000000 00000000 00000001
------------------------------------------
& 00000000 00000000 00000000 00000000
我想实现类似的东西!是否有可能在Java?
答案 0 :(得分:24)
嗯,你可以几乎这样做:
public enum CharEnum // Let's avoid java.lang.* clashes
{
A(1), B(2), C(4), D(8);
private final int mask;
private CharEnum(int mask)
{
this.mask = mask;
}
public int getMask()
{
return mask;
}
}
然后:
CharEnum ch = /* from user */
if ((ch.getMask() & CharEnum.A.getMask()) > 0)
{
// some operation...
}
这在某些情况下很有用,但正如迈克尔所说,你一定要看EnumSet
一般的“值集”选项。
如果你做决定使用值来获取枚举,你可以在枚举本身中加入额外的逻辑:
public enum CharEnum
{
// Other code as before
public boolean overlapsWith(CharEnum ch)
{
return (ch.mask & mask) > 0;
}
}
答案 1 :(得分:5)
(当然,选择Character
作为枚举的名称非常混乱,因为它会与java.lang.Character
产生冲突,并自动导入每个编译单元。
您可以使用ordinal()方法获取与枚举常量关联的整数。无论如何,我觉得你想要实现的目标可以通过枚举定义的方法来实现。我的意思是,Java的枚举比C / C ++更强大,因为你可以将行为与它们联系起来。
public enum Chr {
A {
@Override public void doSomething(int c) {
// some operation ...
}
},
B,
C,
D;
public void doSomething(int c) {
// some default behavior
}
}
发表评论:
您可以定义一个保存此值的字段,并让构造函数初始化它,如下所示:
public enum Chr {
A(1),
B(2),
C(4),
D(8)
;
public Chr(int n) { value = n; }
public final int value;
}
Character ch = ... // from user
if(ch & Chr.A.value) {
...
}
答案 2 :(得分:2)
你可以使用Enum.ordinal()
做类似的事情,但设计真的很糟糕。您应该使用==
进行相等比较,使用EnumSet
进行集合操作。
答案 3 :(得分:2)
我同意Itay,为了进一步了解,我建议您阅读 Effective Java Second Edition ,其中有一整章真正有趣的Java枚举。
答案 4 :(得分:2)
我同意Michael Borgwardt和Jon Skeet的观点,EnumSet
值得关注。我会像你一样选择EnumSet
按位操作,所以我将演示如何使用EnumSet
。
看起来你的 (从现在开始我们称之为Character
enum CharEnum
)CharEnum
被用作比特字段,其中每个枚举都有只设置一位的int值:
A = 00000000 00000000 00000000 00000001
B = 00000000 00000000 00000000 00000010
C = 00000000 00000000 00000000 00000100
D = 00000000 00000000 00000000 00001000
这与EnumSet
为你做的非常相似;它有一个内部位向量,可以自动将每个枚举分配给long
上的一个位。正如JavaDoc所说,“这个类的空间和时间性能应该足够好,可以作为传统的基于int的”位标志“的高质量,类型安全的替代品。” < / p>
以下是如何使用它的示例
public enum CharEnum {
A, B, C, D;
}
然后
EnumSet<CharEnum> ch = /* from user */
if (ch.contains(CharEnum.A)) {
// some operation...
}
无需在任何地方指定位,因此代码更简单!
警告:这只能起作用,因为C#示例中的枚举值每个只设置一个位。如果你有这样的枚举值:
E = 00011000 01110111 11100101 10000101
然后EnumSet
不合适。在这种情况下,你应该看看其中一个答案。