Number for each enum item?
Is it possible to define something like this in java?
C# code:
public enum Character
{
A = 1,
B = 2,
C = 4,
D = 8
}
...
Character ch = /* from user */
if(ch & Character.A)
{
// some operation...
}
for example if ch
set to Character.B
then result of if
will be false
:
ch = 00000000 00000000 00000000 00000010
A = 00000000 00000000 00000000 00000001
---------------------------开发者_JAVA百科---------------
& 00000000 00000000 00000000 00000000
I want to implement something like that! Is it ever possible in Java?
Well, you can nearly do that:
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;
}
}
Then:
CharEnum ch = /* from user */
if ((ch.getMask() & CharEnum.A.getMask()) > 0)
{
// some operation...
}
This can be useful in some situations, but as Michael said you should definitely look at EnumSet
for general "set of values" options.
If you do decide to go for an enum with values, you can put extra logic within the enum itself:
public enum CharEnum
{
// Other code as before
public boolean overlapsWith(CharEnum ch)
{
return (ch.mask & mask) > 0;
}
}
(Of course, choosing Character
as the name of your enum is very confusing as it creates a conflict with java.lang.Character
which is automatically imported into every compilation unit)
You can use the ordinal() method to get the integer associated with an enum constant. Anyway, I got a feeling that what you are trying to achieve may be realized by enum-defined methods. I mean, Java's enum are more powerful than C/C++'s because you can associate behavior with them.
public enum Chr {
A {
@Override public void doSomething(int c) {
// some operation ...
}
},
B,
C,
D;
public void doSomething(int c) {
// some default behavior
}
}
Following your comment:
You can define a field which will hold this value, and have the constructor initialize it, as follows:
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) {
...
}
You could do something like that using Enum.ordinal()
, but it would be really bad design. You should use ==
for equality comparisons and EnumSet
for set operations.
I agree with Itay, and to get a bit further I'll recommend the reading of Effective Java Second Edition having a full chapter really interesting on Java enums.
I agree with Michael Borgwardt and Jon Skeet that an EnumSet
is worth looking at. I would have picked EnumSet
over bitwise operations like you've got, so I will demonstrate how to use EnumSet
.
It looks like your (let's call it Character
enumCharEnum
from now on) CharEnum
is being used like a bit field, where each enum has an int value with just one bit set:
A = 00000000 00000000 00000000 00000001
B = 00000000 00000000 00000000 00000010
C = 00000000 00000000 00000000 00000100
D = 00000000 00000000 00000000 00001000
This is very similar to what an EnumSet
does for you; it has an internal bit vector that automatically assigns each enum to a bit on a long
. As the JavaDoc for it says, "The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags."
Here's an example of how to use it
public enum CharEnum {
A, B, C, D;
}
and then
EnumSet<CharEnum> ch = /* from user */
if (ch.contains(CharEnum.A)) {
// some operation...
}
No need to specify bits anywhere, so it's much simpler code!
A warning: this only works because the enum values in your C# example have only one bit set each. If you had an enum value like this:
E = 00011000 01110111 11100101 10000101
then an EnumSet
would not be appropriate. In that case you should look at one of the other answers here.
精彩评论