È questo codice Java valida?
Domanda
Sto utilizzando Eclipse, ed è perfettamente felice con il seguente codice:
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
}
}
Tuttavia, la piattaforma che sto correndo sul crash alla linea marcata sopra. Con l'incidente, pensa un equivalente di un BSOD. C'è qualcosa di sbagliato con il mio codice, o ho bisogno di perseguire gli sviluppatori del Java VM per la mia piattaforma?
EDIT:
Ok, grazie per le vostre risposte. Si è scoperto essere un bug nel Java VM. Per citare lo sviluppatore, 'gloomyandy',
Questo è un problema noto con interfacce che hanno un inizializzatore statico. E 'fissato nello sviluppo corrente costruisce ...
Soluzione
non vedo alcun problema con questo codice, diverso da quello che se si utilizza Java5 o al di sopra, si dovrebbe essere meglio utilizzare un 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 :-)
}
}
Aggiornamento: per ricreare il valore enum dalla sua rappresentazione di byte, è necessario integrare MessageType
con il seguente (adattato da Effective Java, 2nd Ed Articolo 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);
}
Altri suggerimenti
Sembra ragionevole ...
Che cosa succede se si prendono i "manici MessageType" fuori della classe, si pianta ancora?
Il codice stesso è perfettamente sana. Posso compilare ed eseguire perfettamente bene sulla mia macchina Win7 (con java6); suona come stai usando qualche sistema insolito?
Come tutti ha detto, dovrebbe funzionare.
Si può provare questo:
public class MessageTest implements MessageType
{
public static void main(String[] args)
{
int b = MESSAGES.length; // no MessageType here
}
}
(MessageType
non è necessaria in quanto la classe sta attuando esso).
Ho ancora preferirei il modo Péter Török suggerito.