utiliza uso switch sentencia que para implementacion ejemplo con java switch-statement long-integer language-design

uso - switch java ejemplo menu



¿Por qué su tipo de datos de la instrucción switch no puede ser largo, Java? (4)

Aquí hay un extracto de los tutoriales de Java de Sun :

Un conmutador funciona con los tipos de datos primarios byte , short , char e int . También funciona con tipos enumerados (descritos en Clases y herencia) y algunas clases especiales que "ajustan" ciertos tipos primitivos: Character , Byte , Short y Integer (descritos en Objetos de datos simples).

Debe haber una buena razón por la que no se permite el tipo de datos primitivos long . Alguien sabe lo que es?


Creo que, en cierta medida, probablemente fue una decisión arbitraria basada en el uso típico de switch.

Un interruptor se puede implementar esencialmente de dos maneras (o en principio, una combinación): para un número pequeño de casos, o aquellos cuyos valores están muy dispersos, un interruptor se convierte esencialmente en el equivalente de una serie de ifs en una variable temporal (el el valor que se enciende solo debe evaluarse una vez). Para un número moderado de casos que tienen un valor más o menos consecutivo, se usa una tabla de interruptores (la instrucción TABLESWITCH en Java), donde la ubicación a la que se puede saltar se busca efectivamente en una tabla.

Cualquiera de estos métodos podría, en principio, utilizar un valor largo en lugar de un entero. Pero creo que probablemente fue solo una decisión práctica equilibrar la complejidad del conjunto de instrucciones y el compilador con la necesidad real: los casos en los que realmente necesita cambiar durante un tiempo prolongado son tan raros que es aceptable tener que volver a escribir como series de declaraciones IF, o redondeo de alguna otra manera (si los valores largos en cuestión están muy juntos, puede cambiar su código Java sobre el resultado int de restar el valor más bajo).


Debido a que el índice de la tabla de búsqueda debe ser de 32 bits.


Debido a que no implementaron las instrucciones necesarias en el bytecode y realmente no desea escribir tantos casos, no importa cuán "listo para la producción" esté su código ...

[EDITAR: Extraído de los comentarios sobre esta respuesta, con algunas adiciones en el fondo]

Para ser exactos, 2³² es una gran cantidad de casos y cualquier programa con un método lo suficientemente largo como para contener más de lo que va a ser absolutamente horrible! En cualquier idioma. (La función más larga que conozco en cualquier código en cualquier idioma es un poco más de 6k de SLOC, sí, es un gran switch , y es realmente inmanejable). Si realmente estás atascado en tener un long , deberías tener solo un int o menos, entonces tienes dos alternativas reales.

  1. Use alguna variante en el tema de las funciones hash para comprimir el long en un int . ¡El más simple, solo para usar cuando tienes el tipo incorrecto, es simplemente lanzar! Más útil sería hacer esto:

    (int) ((x&0xFFFFFFFF) ^ ((x >>> 32) & 0xFFFFFFFF))

    Antes de encender el resultado. Tendrá que encontrar la manera de transformar los casos contra los que está probando. Pero en realidad, eso sigue siendo horrible, ya que no aborda el problema real de muchos casos.

  2. Una solución mucho mejor si está trabajando con un gran número de casos es cambiar su diseño para usar un Map<Long,Runnable> o algo similar, de modo que esté buscando cómo enviar un valor en particular. Esto le permite separar los casos en varios archivos, que es mucho más fácil de administrar cuando el número de casos aumenta, aunque se vuelve más complejo organizar el registro de la clase de implementación involucrada (las anotaciones pueden ayudar al permitirle construir el código de registro automáticamente).

    FWIW, hice esto hace muchos años (cambiamos al J2SE 1.2 recientemente lanzado a mitad del proyecto) cuando construimos un motor de bytecode personalizado para simular hardware masivamente paralelo (no, reutilizar la JVM no hubiera sido adecuado debido a la radicalidad se utilizaron diferentes modelos de valor y ejecución) y simplificó enormemente el código en relación con el gran switch que estaba utilizando la versión C del código.

Para reiterar el mensaje para llevar a casa, querer switch por long es una indicación de que, o bien está equivocado en su programa o de que está construyendo un sistema con tantas variaciones involucradas, que debería estar usando clases. Tiempo para un replanteamiento en cualquier caso.


Un largo, en arquitecturas de 32 bits, está representado por dos palabras . Ahora, imagínese lo que podría suceder si la sincronización insuficiente, la ejecución de la instrucción switch cambia mucho con sus 32 bits altos de una escritura y los 32 bajos de otra. Podría intentar ir a ... ¡quién sabe dónde! Básicamente en algún lugar al azar. Incluso si ambas escrituras representaran casos válidos para la instrucción de cambio, su combinación divertida probablemente no llevaría ni a la primera ni a la segunda, o, lo que es peor, ¡podría llevar a otro caso válido, pero no relacionado!

Al menos con un int (o tipos más pequeños), sin importar qué tan mal lo arruines, la instrucción switch leerá al menos un valor que alguien escribió en realidad , en lugar de un valor "de la nada".

Por supuesto, no sé la razón real (¡han pasado más de 15 años, no he prestado atención durante tanto tiempo!), Pero si te das cuenta de lo inseguro e impredecible que podría ser esa construcción, estarás de acuerdo en que Esta es definitivamente una muy buena razón para no tener un interruptor en los largos (y, como se pretende, habrá máquinas de 32 bits, esta razón seguirá siendo válida).