Enums

  • Thread starter Gilbert Ostlethwaite
  • Start date
G

Gilbert Ostlethwaite

Can I have an Enum whose assigned value is a byte[]? Something on the
lines of

public enum Command {

Command_1(byte[]{0x01,0x02,0x03});
}

If the answer is yes, could someone help with the syntax to make this
work please.

Regards
 
M

Mayeul

Gilbert said:
Can I have an Enum whose assigned value is a byte[]? Something on the
lines of

public enum Command {

Command_1(byte[]{0x01,0x02,0x03});
}

If the answer is yes, could someone help with the syntax to make this
work please.

you sure can, and you almost had it right.

The way to declare inline byte arrays that way is:

new byte[] {0x01, 0x02, 0x03}
 
R

Roedy Green

Can I have an Enum whose assigned value is a byte[]? Something on the
lines of

public enum Command {

Command_1(byte[]{0x01,0x02,0x03});
}

You are confusing Java enums with C++ enums. Java enums don't have
assigned values. You can, however, associate values with each enum
constant and write method to convert enum value to that associated
value or vice versa.

See http://mindprod.com/jgloss/enum.html
 
M

Mayeul

Mayeul said:
Gilbert said:
Can I have an Enum whose assigned value is a byte[]? Something on the
lines of

public enum Command {

Command_1(byte[]{0x01,0x02,0x03});
}

If the answer is yes, could someone help with the syntax to make this
work please.

you sure can, and you almost had it right.

The way to declare inline byte arrays that way is:

new byte[] {0x01, 0x02, 0x03}

Please disregard that. I hadn't noticed the "assigned value" part. As
Roedy pointed out, Java enums do not have assigned values.
 
M

Mike Amling

Gilbert said:
Can I have an Enum whose assigned value is a byte[]? Something on the
lines of

public enum Command {

Command_1(byte[]{0x01,0x02,0x03});
}

If the answer is yes, could someone help with the syntax to make this
work please.

/** untested */
public enum Command {

Command_1(new byte[]{1, 2, 3}),
Command_2(new byte[]{6, 5, 4});

private final byte[] sequence;

private Command(final byte[] code) {
this.sequence=code;
}

public byte[] getSequence() {
return this.sequence;
// or
// return (byte[])this.sequence.clone();
// to prevent the caller from changing the array contents
}
}

Is this what you were looking for?

--Mike Amling
 
L

Lew

Mayeul said:
Mayeul said:
Gilbert said:
Can I have an Enum whose assigned value is a byte[]? Something on the
lines of

public enum Command {

Command_1(byte[]{0x01,0x02,0x03});
}

If the answer is yes, could someone help with the syntax to make this
work please.

you sure can, and you almost had it right.

The way to declare inline byte arrays that way is:

new byte[] {0x01, 0x02, 0x03}

Please disregard that. I hadn't noticed the "assigned value" part. As
Roedy pointed out, Java enums do not have assigned values.

Sure they do - arbitrary ones and an arbitrary number of them of arbitrary
types. Mike Amling showed a good example of a byte [] value.
 
R

Roedy Green

Please disregard that. I hadn't noticed the "assigned value" part. As
Roedy pointed out, Java enums do not have assigned values.

Sure they do - arbitrary ones and an arbitrary number of them of arbitrary
types. Mike Amling showed a good example of a byte [] value.

In C++ you assign an int to each Enum constant. This is the binary
value it has in RAM. Java does not work that way. Enums in Java are
represented as the addresses of enum constant objects. You can
discover an associated ordinal, but you can't assign it. You can
include additional fields on each enum constant, but none of them
represent the official value of the enum. With a bit of fiddling, you
can pull off something that behaves very much like C++ however, which
is what Lew was referring to.
 
L

Lew

Roedy said:
In C++ you assign an int to each Enum constant. This is the binary
value it has in RAM. Java does not work that way. Enums in Java are
represented as the addresses of enum constant objects. You can
discover an associated ordinal, but you can't assign it. You can
include additional fields on each enum constant, but none of them
represent the official value of the enum. With a bit of fiddling, you
can pull off something that behaves very much like C++ however, which
is what Lew was referring to.

However, there is rarely if ever to force Java enums to look like C++ enums in
that way. It suffices that, because enums are classes, you can assign all
kinds of attributes to them. You can assign your own ordinal, but chances are
that's a hack you don't need. The enum constants themselves work just fine
and they're 'switch'-friendly. You can read the ordinal that Java assigns the
enum constants. Avoid needing to control that value.
 
W

Wojtek

Lew wrote :
However, there is rarely if ever to force Java enums to look like C++ enums
in that way. It suffices that, because enums are classes, you can assign all
kinds of attributes to them. You can assign your own ordinal, but chances
are that's a hack you don't need. The enum constants themselves work just
fine and they're 'switch'-friendly. You can read the ordinal that Java
assigns the enum constants. Avoid needing to control that value.

Until you need to persist the Enum.

Since the Java compiler can assign any value it wants to the ordinal
you cannot reply on it when persisting. You DO need to assign a fixed
value which can be persisted, and later married up to the Enum for
"switch" etc processing.
 
A

Alessio Stalla

Lew wrote :





Until you need to persist the Enum.

Since the Java compiler can assign any value it wants to the ordinal
you cannot reply on it when persisting. You DO need to assign a fixed
value which can be persisted, and later married up to the Enum for
"switch" etc processing.

You can persist the name of the constant, and retrieve the Enum
instance with Enum.valueOf(MyEnum.class, name). Or, depending on the
context, you can persist the serialized Enum (enums are serializable
by default).

Alessio
 
L

Lew

As Alessio pointed out, that's automatic with enums already, without
extra coding.

switch( Color.valueOf( name ) )
{
case RED: ...; break;
case BLUE: ...; break;
...
}

Alessio said:
You can persist the name of the constant, and retrieve the Enum
instance with Enum.valueOf(MyEnum.class, name).

Or, for an enum 'Foo', use 'Foo.valueOf( name )'.
Or, depending on the context, you can persist the serialized Enum
(enums are serializable by default).

Another thing you can do is override 'toString()' to return some
custom value, and add a static method 'fromString(String)' that
returns the enum instance whose 'toString()' corresponds to the
argument.

That approach can be generalized for identification types other than
'String'.
 
W

Wojtek

Alessio Stalla wrote :
You can persist the name of the constant, and retrieve the Enum
instance with Enum.valueOf(MyEnum.class, name). Or, depending on the
context, you can persist the serialized Enum (enums are serializable
by default).

Ok.

But, silly me, I sometimes rename Enum values. Yes, yes, poor design
and all, but it happens.
 
L

Lew

Alessio Stalla wrote :
Wojtek said:
Ok.

But, silly me, I sometimes rename Enum values. Yes, yes, poor design
and all, but it happens.

And that doesn't risk changing the ordinal? Or if there were a way to
set the ordinal (as there is, as long as by "ordinal" you mean a
custom value retrieved by a method 'getOrdinal()') what's to prevent
you from changing that?
 
W

Wojtek

Lew wrote :
Alessio Stalla wrote :



And that doesn't risk changing the ordinal? Or if there were a way to
set the ordinal (as there is, as long as by "ordinal" you mean a
custom value retrieved by a method 'getOrdinal()') what's to prevent
you from changing that?

// do not change as it is persisted!
private static final int MY_ENUM_ID = 1;

public enum IsEnum
{
MY_ENUM(MY_ENUM_ID);

private int id;

private IsEnum( int databaseID )
{
id = databaseID;
}

public int getDatabaseID()
{
return id;
}
}

and then, of course, some code to scan the enums and find the id you
are looking for.

This is safe against the Java compiler setting ordinals and renaming
enums.
 
L

Lew

Lew wrote :






// do not change as it is persisted!
private static final int MY_ENUM_ID = 1;

public enum IsEnum
{
   MY_ENUM(MY_ENUM_ID);

   private int id;

   private IsEnum( int databaseID )
   {
     id = databaseID;
   }

   public int getDatabaseID()
   {
      return id;
   }

}

and then, of course, some code to scan the enums and find the id you
are looking for.

This is safe against the Java compiler setting ordinals and renaming
enums.

But it is not safe against the programmer redefining 'MY_ENUM_ID',
which is the same degree of change as altering the enum constant name
or an assigned string name. It's equivalent to the suggestion
upthread to add 'fromString()' and override 'tostring()' to match,
with a 'String' identifier instead of an 'int', and has the same
degree of safety (danger).

All you really show in your example is substitution of one constant,
the 'int', for another, the 'enum' value. Enums are a type-safe
replacement for compile-time constants such as 'MY_ENUM_ID'; using
them together like that is redundant.

And buys nothing.
 
W

Wojtek

Lew wrote :
But it is not safe against the programmer redefining 'MY_ENUM_ID',
which is the same degree of change as altering the enum constant name
or an assigned string name. It's equivalent to the suggestion
upthread to add 'fromString()' and override 'tostring()' to match,
with a 'String' identifier instead of an 'int', and has the same
degree of safety (danger).

Not true. The comment warning is there. But renaming the enum may
produce greater code readability. Whereas changing the constant
improves nothing and so is more or less immune to changes, that is a
future programmer would have no incentive to change it.

Heck, I could have used:
MY_ENUM(1)

just as easily. And after the compiler creates the byte code that is
probably what it ends up as. I just like to break it out...
All you really show in your example is substitution of one constant,
the 'int', for another, the 'enum' value. Enums are a type-safe
replacement for compile-time constants such as 'MY_ENUM_ID'; using
them together like that is redundant.

Not redundant. An int is an int, but an enum can only be THAT enum.
Which is why enums exist in the first place.

But since ordinal values are under the compiler's control I use a value
which is under MY control for persistance.
 
R

Roedy Green

Since the Java compiler can assign any value it wants to the ordinal
you cannot reply on it when persisting.

The docs say it uses the enum constant name for persisting with
serialisation. So you don't need to roll your own value.
 
R

Roedy Green

And that doesn't risk changing the ordinal?

The ordinal is assigned in the physical order you specify the enum
constants. You can disturb that by tidying alphabetically, or by
adding a new constant.

If you keep the constants in some logical order, the changing ordinal
causes no practical problems. You don't have the same problem you have
in C/C++ where the ordinal is the persisted value.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,480
Members
44,900
Latest member
Nell636132

Latest Threads

Top