cast byte to enum
I have the following code:
public enum PortableTypes { Boolean, etc...};
public void testConversion() {
byte b = 5;
PortableTypes type = (PortableTypes)b;
}
When I compile, I am told that these are inconvertible types. I was unaware that something as simple as this would be left out of java. Am I missing something, or does Java just not support casting into an enum at all? I tested with an int as well, and it failed.
If this is not supported, what is the easiest workaround?
EDIT:
Since everyone keeps complaining about "bad design", I'll explain a little further. I am using an enum to represent the types that you can send using my TcpServer. The packet is sent with this type, and on the receiving side I look at the type and use it to convert the bytes that are read from the packet into usable data. Obviously you can't send an enum using an OutputStream, so I need to convert the enum value into a numerical value to be sent. I disagree with the idea that this is "bad design", I think that Enums are indeed supposed to be used for e开发者_StackOverflow中文版xactly this purpose, but that this design does not work in Java because it is strongly typed.
You're probably thinking of enum
as something like we have in c/C++ or C#, which is basically a syntax sugar for declaring constants.
Java's enum
is a completely different beast though... It is a built-in implementation of the Typesafe Enum pattern. Since it is strongly typed, it is not possible to directly cast a enum from a byte, or even from an integer.
But all enums are complete classes in Java, so nothing stops you from implementing an additional method that does that conversion for you.
Hope it helps.
Edit: Again, I'm not a Java programmer, but I guess something like this would work:
public enum PortableTypes {
Boolean,
Type2,
Type3;
public static PortableTypes convert(byte value) {
return PortableTypes.values()[value];
}
};
public void testConversion() {
byte b = 5;
PortableTypes type = PortableTypes.convert(b);
}
Let me know if it works.
Java enums have ordinals to help you out.
To get from a constant to a number, call WHATEVER.ordinal()
. It returns the index of the constant in the declaration order. So, for:
enum Underwear { BRIEFS, BOXERS };
Underwear.BRIEFS.ordinal()
is 0, and Underwear.BOXERS.ordinal()
is 1.
To get from a number to the enum object, call values()
and index the returned array.
The horse's mouth here is: http://download.oracle.com/javase/6/docs/api/java/lang/Enum.html
Your most effective solution would be to pass messages back and forth with an ObjectOutputStream
. This is good for a number of reasons.
- Built in
enum
serialization - Extendability to more complex message passing is smoother
- The ability to pass in callbacks and parameters is baked in as well!
Or write a static getter method:
PortableTypes.get(b);
public static PortableTypes get(byte b) {
return PortableTypes.values()[b];
}
An enum is designated a type (though it defaults to a value of int usually in persistence etc...) it actually has a type. The bigger question is why you want to cast it as I would file it under "Bad practice" generally. Strong typing is a major advantage of modern languages.
If you just need a byte value read up on enum design patterns in Java.
If you need the value you can do something like:
enum SomeEnum
{
a((byte)0x01),
b((byte)0x02),
c((byte)0x03),
d((byte)0x04);
byte byteVal;
SomeEnum(byte b)
{
byteVal = b;
}
//Continued long winded example
public MyNum replacementValueOf(byte b)
{
for(MyNum num : MyNum.values())
if(b == num.getByte())
return num;
throw new RuntimeException("Your byte " + b + " was not a backing value for MyNum.");
}
}
I was giving an in-depth answer, but I agree with the posts above, rethink the design pattern.
I'm not sure it's a good idea to do this.
You could do PortableTypes.values()[b]
but it would be better to rethink the design.
You could try making a method for your enum that takes in a byte. It might look something like this:
public enum PortableTypes {
Boolean, //etc....
Int;
public statc PortableTypes fromByte(byte b) {
for(PortableTypes t : values())
{
if(t.ordinal() == (int)b)
return t;
}
return null; //or throw exception
}
}
I don't have an IDE handy right now, but I believe something like this would work. Hope this helps.
You can only cast from a super type to a derived type, if the type is in fact a derived type. Enums aren't kinds of Byte or vice versa.
精彩评论