Search code examples
javalejos-nxj

Is this valid Java code?


I'm using Eclipse, and it is perfectly happy with the following code:

public interface MessageType
{
    public static final byte   KICK     = 0x01;
    public static final byte   US_PING  = 0x02;
    public static final byte   GOAL_POS = 0x04;
    public static final byte   SHUTDOWN = 0x08;
    public static final byte[] MESSAGES = new byte[] {
        KICK,
        US_PING,
        GOAL_POS,
        SHUTDOWN
    };
}

public class MessageTest implements MessageType
{
    public static void main(String[] args)
    {
        int b = MessageType.MESSAGES.length;    //Not happy
    }
}

However, the platform that I'm running it on crashes at the line marked above. By crash, think an equivalent of a BSOD. Is there anything wrong with my code, or do I need to pursue the developers of the Java VM for my platform?


EDIT:

Ok, thanks for your responses. It turned out to be a bug in the Java VM. To quote the developer, 'gloomyandy',

This is a known problem with interfaces that have a static initializer. It is fixed in the current development builds...


Solution

  • I don't see any problem with this code, other than that if you are using Java5 or above, you would be better off using an enum:

    public enum MessageType
    {
        KICK     (0x01),
        US_PING  (0x02),
        GOAL_POS (0x04),
        SHUTDOWN (0x08);
    
        private byte value;
        MessageType(byte value) { this.value = value; }
        byte getValue() { return value; }
    }
    
    public class MessageTest
    {
        public static void main(String[] args)
        {
            int b = MessageType.values().length;    //Should be happy :-)
        }
    }
    

    Update: to recreate the enum value from its byte representation, you need to supplement MessageType with the following (adapted from Effective Java, 2nd Ed. Item 31):

    private static final Map<Byte, MessageType> byteToEnum = new HashMap<Byte, MessageType>();
    
    static { // Initialize map from byte value to enum constant
      for (MessageType type : values())
        byteToEnum.put(type.getValue(), type);
    }
    
    // Returns MessageType for byte, or null if byte is invalid
    public static MessageType fromByte(Byte byteValue) {
      return byteToEnum.get(byteValue);
    }