每个枚举项的编号是什么?

7

你能否在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中是否有可能?

5个回答

25

好的,你几乎可以这样做:

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...
}

这在某些情况下可能会很有用,但正如Michael所说,您应该绝对查看EnumSet以获取通用的“值集合”选项。

如果您确实决定使用带有值的枚举,也可以在枚举本身中放入额外的逻辑:

public enum CharEnum
{
    // Other code as before

    public boolean overlapsWith(CharEnum ch)
    {
        return (ch.mask & mask) > 0;
    }
}

1
你应该在那里添加一些括号:if ((ch.getMask() & CharEnum.A.getMask()) > 0) - True Soft

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
我同意Michael Borgwardt和Jon Skeet的观点,认为应该使用EnumSet。我会选择EnumSet而不是像你所用的位运算,因此我将演示如何使用EnumSet。
它看起来像你的Character枚举(我们现在称之为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的“位标志”的高质量、类型安全的替代品使用。"

下面是一个如何使用它的例子:

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,那么你应该查看这里的其他答案。

2
您可以使用Enum.ordinal()来实现类似的功能,但这将是一个非常糟糕的设计。您应该使用==进行相等比较,并使用EnumSet进行集合操作。

2

我同意Itay的观点,并建议阅读Effective Java第二版,其中有一个章节非常有关于Java枚举。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接