Tengo el siguiente código:


public enum PortableTypes { Boolean, etc...};

public void testConversion() {
  byte b = 5;
  PortableTypes type = (PortableTypes)b;
}

Al compilar, me han dicho que estos son los tipos de suspender la convertibilidad. Yo era consciente de que algo tan simple como esto iba a quedar fuera de java. Me estoy perdiendo algo, o Java no sólo de apoyo de fundición en una enumeración en todo? He probado con un int como bien, y fracasó.

Si esto no es posible, ¿cuál es la solución más sencilla?

EDICIÓN:

Ya que todo el mundo sigue quejándose de «mal diseño», voy a explicar un poco más. Estoy utilizando un enum para representar los tipos que usted puede enviar a través de mi TcpServer. El paquete se envía con este tipo, y en el lado de recepción miro el tipo y utilizarlo para convertir los bytes que se leen desde el paquete en datos utilizables. Obviamente, usted no puede enviar un enum utilizando un OutputStream, por lo que necesito para convertir el valor de enumeración en un valor numérico a ser enviado. Estoy en desacuerdo con la idea de que este es «mal diseño», creo que las Enumeraciones son, de hecho, supone que se utiliza para este propósito, pero que este diseño no funciona en Java ya que es inflexible.

  • «Algo tan simple como esto»… lo Siento, pero ¿qué es esto?
  • Es una simple conversión de bytes Enum. Así que en mi ejemplo, usted podría conseguir la 6ª entrada en el Enum.
  • ¿por qué no puede usted enviar un enum utilizando un outputstream? Si usted está usando un objectoutputstream se puede enviar como cualquier otro objeto.
  • Una lección que he aprendido con Java zócalo de la obra es «Si no estás usando la serialización para enviar sus mensajes, no hay mejor que ser una maldita buena razón para ello.»
  • Si usted necesita para convertir una enumeración de un byte o de tipo int, entonces tu probablemente no usarlos correctamente… al menos en el mundo de java
  • Estoy tratando de implementarlo con el ObjectOutputStream ahora. Si usted publicar una respuesta, voy a marcar la suya como la solución, ya que esta es la forma más fácil (y más potente) respuesta que he visto hasta ahora.

InformationsquelleAutor Darkhydro | 2011-04-04

8 Comentarios

  1. 2

    La solución más eficaz sería la de transmitir los mensajes de ida y vuelta con un ObjectOutputStream. Esto es bueno para un número de razones.

    1. Construido en enum serialización
    2. Posibilidad de ampliación hasta las más complejas paso de mensajes es más suave
    3. La capacidad de pasar en las devoluciones de llamada y los parámetros se cuece en así!
    • gracias por publicar esto. Sin duda la mejor solución. Esta clase es realmente potente, me alegro de que usted me presentó a él.
    • no hay problema. Me encontré con el mismo problema hace tres semanas tratando de pasar de Cadenas de caracteres y bytes y todo tipo de cosas a través de un socket. Cada tipo de mensaje fue diferente, tuve todo tipo de interruptor de casos pasando. Ahora tengo un resumen Message clase y voy solo Message m = in.readObject(); m.performCallback(motor);` y simplemente funciona. solo funciona. A la derecha fuera de la caja. Nada de imaginación o de instalación de ná.
    • Considere la posibilidad de leer sobre el stackoverflow.com/questions/5453522/… Es una pregunta que me pidió que estuvo a cargo de algunos de los conceptos básicos, y fue muy instructivo para mí.
    • sí que hace un montón de sentido. su muy bien que funciona tan fácilmente. como 3 líneas de código. También se podría trabajar con el polimorfismo de la derecha? así que yo sólo podía tener el mismo método para todas las sub-clases de mi objeto de base y que va a elegir el método correcto basado en lo que la clase es en realidad leer en
    • Eso es exactamente correcto. Mi pregunta fue originalmente acerca de «¿Cómo puedo determinar el tipo?» y la respuesta es «siempre y cuando usted sabe su tipo primario (el único tipo que usted envíe a través de) usted no necesita saber su tipo real.» Yo era un feliz dev ese día. 🙂
  2. 6

    Probablemente estás pensando enum como algo como el que tenemos en c/C++ o C#, que es básicamente una sintaxis de azúcar para declarar constantes.

    Java enum es una bestia completamente diferente, aunque… es un built-in de la aplicación de la Typesafe Enum patrón. Ya que es inflexible, no es posible lanzar directamente una enumeración de un byte, o incluso de un entero.

    Pero todas las enumeraciones son completar las clases en Java, así que nada te impide la aplicación de un método adicional que hace que la conversión para usted.

    Espero que ayude.

    Edición: de Nuevo, yo no soy un programador de Java, pero supongo que algo como esto iba a funcionar:

    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);
    }

    Hágamelo saber si funciona.

    • hay una solución para esto, o tengo que declarar un montón de static final enteros…?
  3. 3

    Java enumeraciones han ordinales para ayudarle a salir.

    A obtener a partir de una constante para un número de llamada WHATEVER.ordinal(). Devuelve el índice de la constante en el orden de declaración. Así, para:

    enum Underwear { BRIEFS, BOXERS };

    Underwear.BRIEFS.ordinal() es 0, y Underwear.BOXERS.ordinal() es 1.

    A obtener a partir de un número a la enumeración de objetos, llamada values() y el índice de la matriz devuelta.

    La boca del caballo es: http://download.oracle.com/javase/6/docs/api/java/lang/Enum.html

    • ¿qué es una variable ordinal (), y qué hace? y ¿cuál es el tipo de LO que sea? No vi este método de la enumeración o la constante
    • Java le da un .ordinal() método en cada uno de los enumeración de elementos. Si usted agregar más métodos para su enum (como por otras respuestas aquí) también aparecen en el mismo lugar.
    • simplemente es su número de secuencia en el orden de declaración. La otra dirección va con EnumType.values()[i].
  4. 2

    O escribir estático de un método getter:

    PortableTypes.get(b);
    
    public static PortableTypes get(byte b) {
      return PortableTypes.values()[b];
    }
    • Una especie de largo aliento de reemplazo para PortableTypes.los valores de()[b].
    • De largo aliento, tal vez. Pero más orientado a objetos, no?
    • Así, podemos debatir todo el día. Uno de los puntos. Él podría hacer el mismo tipo de OO envolver en su país natal, C#, después de todo.
  5. 2

    Una enumeración se designa un tipo (aunque el valor predeterminado es un valor de tipo int generalmente en la persistencia etc…) en realidad tiene un tipo. La pregunta más grande es la razón por la que quieres lanzar como me gustaría archivo en el apartado de «Mala práctica» en general. Tipado fuerte es una de las principales ventajas de lenguas modernas.

    Si usted sólo tiene un valor de byte leer sobre enum patrones de diseño en Java.

    Si usted necesita el valor, puedes hacer algo como:

    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.");
        }
    }

    Me estaba dando en profundidad la respuesta, pero estoy de acuerdo con los puestos de arriba, a repensar el patrón de diseño.

    • Una especie de largo aliento de reemplazo para ordinal().
    • ¿cómo puedo reescribir el código de ejemplo en mi pregunta con este nuevo Enum?
    • Ordinal es desanimado, ya que el orden de declaración de los saltos de código (silencio.)
    • Igual que en C y C++. Si tu propósito en la vida es para asignar nombres a los números que comiencen con a 0, es perfectamente bien.
    • He probado esta solución, pero todavía no podía lanzar un valor de byte en mi enum, y no puedo utilizar el constructor (fue privado). de lo contrario, esta sería mi favorito respuesta.
    • no puedes lanzarlo (que en realidad son un tipo) si desea utilizar se deberá agregar un método como «public static SomeEnum getValue(byte b);» es por eso que me sugiere el replanteamiento de los patrones de diseño, usted puede mirar para arriba y ver el ejemplo. Lo que está haciendo el ordinal enfoque realmente es una mejor manera a la mano. Sin embargo, es terrible para el mantenimiento por lo que tiendo a hacer lo anterior (glowcoder alude a ello).
    • después de leer sus comentarios de arriba, sí, lo estoy haciendo de arriba es probablemente el más fácil de mantener el diseño. Usted quiere asegurarse de que el paquete utiliza la misma información en ambos lados y que permanece estático. Mientras valueOf(int i) trabajará a través de un & 0x000000FF para conseguir tu byte, si usted tiene más de 0xFF estados o cambiar el orden es un problema. Alternativamente, si está en tiempo de ejecución sólo (byte)(Enum.VALOR.ordinal() & 0xFF) -> para el servidor y Enumeración.valueOf((int)(packetByte & 0xFF) para la vuelta.

  6. 1

    No estoy seguro de que es una buena idea hacer esto.
    Usted podría hacer PortableTypes.values()[b] pero sería mejor para repensar el diseño.

    • en serio? Lo hago todo el tiempo en C#. ¿Por qué habría de ser esto un problema? Las enumeraciones son como una colección de static final enteros, pero con su propio tipo. La razón por la que hago esto es lo que se necesita para enviar el tipo como un int.
    • ver mi respuesta, soy un programador de C#, pero AFAIK el Java enum es, de hecho, mucho superior para la implementación en C#.
    • ¿Qué hay de malo con los valores de() y ordinales(). Es por eso que hay allí.
    • ¿qué es una variable ordinal (), y qué hace?
    • son como una colección de static final enteros, pero con su propio tipo.» – En C#, sí. No en Java.
    • son como una colección de static final enteros». En última instancia, todo esto es sólo una colección de 0 y 1 en la memoria. Pero los tipos de datos que se inventaron precisamente para evitar esta confusión.

  7. 1

    Usted podría tratar de hacer un método para su enumeración que se lleva en un byte. Podría ser algo como esto:

    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
        }
    }

    No tengo una IDE a mano ahora mismo, pero creo que algo como esto iba a funcionar. Espero que esto ayude.

    • PortableTypes.java:10: ordinal has private access in java.lang.Enum if(t.ordinal == (int)b) t.ordinal () lo hará por ti.
    • Gracias, corregido. Aunque, debo mencionar que no uso esto como que hay mejores soluciones que ya han publicado jaja.
    • Su fromByte método debe ser static.
  8. 0

    Sólo se puede lanzar desde un super tipo a un tipo derivado, si el tipo es en realidad un tipo derivado. Las enumeraciones no son tipos de Byte o viceversa.

Dejar respuesta

Please enter your comment!
Please enter your name here