Java Switch y String son buenos

Sabemos que Java Switch admite los tipos byte, short e int. En JDK 1.5, se admitían los tipos de enumeración, y en JDK 1.7, se admitían los tipos de cadena. Entonces, ¿por qué no puede admitir el tipo largo? Obviamente, es un tipo numérico como byte, short e int, entonces, ¿por qué admite el tipo String?
1. Conclusiones
Primero hablemos de la conclusión: la
capa inferior de switch usa el tipo int para emitir juicios. Incluso los tipos de enumeración y String se transforman eventualmente en el tipo int. Dado que el tipo largo indica que el rango es mayor que el tipo int, no se admite el tipo largo.
La siguiente es una descripción detallada de cómo se convierte cada tipo en un tipo int. El comando de compilación utilizado es javac, y el sitio web de descompilación es: javare.cn
2. ¿Cómo se convirtió el tipo de enumeración en el tipo int?
Antes del experimento, di por sentado que se calculó en función del campo de tipo int de la enumeración (porque la enumeración general es un tipo int y un tipo de cadena), pero después de otro pensamiento, en caso de que la enumeración no tenga un int type Fields, en caso de que haya varios campos int, por lo que definitivamente no es el caso, veamos el experimento a continuación.
Defina dos clases de enumeración, una clase de enumeración tiene un atributo de tipo int y un atributo de tipo de cadena, y la otra clase de enumeración tiene solo un atributo de cadena:
public enum SexEnum {MALE (1, "男"), FEMALE (0, "女"); private int type; private String name; SexEnum (int type, String name) {this.type = type; this.name = name ;}} public enum Sex1Enum {MALE ("男"), FEMALE ("女"); private String name; Sex1Enum (String name) {this.name = name;}} Copie el código
y escriba una clase de prueba, y haga two Los valores de retorno correspondientes FEMALE y MALE de un interruptor de enumeración son diferentes:
public class SwitchTest {public int enumSwitch (SexEnum sex) {switch (sex) {case MALE: return 1; case FEMALE: return 2; default: return 3 ;}} public int enum1Switch (Sex1Enum sex) {switch (sex) {case FEMALE: return 1; case MALE: return 2; default: return 3;}}} Copia el código
Descompila estas clases:
// SexEnum.class public enum SexEnum {MALE (1, “鐢 ”), FEMALE (0, “濂 ”); tipo int privado; nombre de cadena privada; // $ FF: campo sintético privado estático final SexEnum [] $ VALUES = new SexEnum [] {MASCULINO, FEMENINO}; SexEnum privado (int var3, String var4) {this.type = var3; this.name = var4;}} // Sex1Enum.class public enum Sex1Enum {MALE ("鐢 ”), FEMALE (“ 濂 ”); Private String name; // $ FF: campo sintético private static final Sex1Enum [] $ VALUES = new Sex1Enum [] {MALE, FEMALE}; private Sex1Enum (String var3) {this .name = var3;}} Copie el código
Descompile estas dos clases de enumeración y descubra que hay una matriz $ VALUES adicional, que contiene todos los valores de enumeración. Continúe descompilando la clase de prueba:
// SwitchTest $ 1.class import com.example.express.test.Sex1Enum; import com.example.express.test.SexEnum; // $ FF: clase sintética clase SwitchTest $ 1 {// $ FF : campo sintético estático final int [] S witch M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprést e s t SexEnum; // $ FF: campo sintético static final int []S witch M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprést e s t Sex1Enum = new int [Sex1Enum.values ​​(). length]; static {try {S witch M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprést e s t Sex1Enum [Sex1Enum.FEMALE.ordinal ()] = 1; } captura (NoSuchFieldError var4) {; } prueba {S witch M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprést e s t Sex1Enum [Sex1Enum.MALE.ordinal ()] = 2; } captura (NoSuchFieldError var3) {; }S witch M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprést e s t SexEnum = new int [SexEnum.values ​​(). length]; prueba {S witch M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprést e s t SexEnum [SexEnum.MALE.ordinal ()] = 1; } captura (NoSuchFieldError var2) {; } prueba {S witch M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprésT E S T SexEnum [SexEnum.FEMALE.ordinal ()] = 2;} the catch (NoSuchFieldError var1) {;}}} copia el código
generado en la primera clase llamada link SwitchTest $ 1.java del cual define dos piezas Por ejemplo, el orden de agregar los dos elementos de la matriz es exactamente el mismo que el orden de llamar a la clase de conmutador en la clase de prueba.
Inserte la descripción de la imagen aquí

El subíndice del elemento de enumeración en la matriz está determinado por la función ordinal (), que devuelve el número ordinal del elemento de enumeración en la clase de enumeración.
Aquí ya sabemos que en la instrucción switch, el elemento de enumeración se convierte al tipo int de acuerdo con el número de secuencia del elemento de enumeración en la enumeración. Finalmente, observe el resultado de la descompilación de la clase de prueba para verificar:
// SwitchTest.class import com.example.express.test.Sex1Enum; import com.example.express.test.SexEnum; import com.example.express.test. SwitchTest .1; clase pública SwitchTest {public int enumSwitch (SexEnum var1) {switch (1. S bruja M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprést e s t SexEnum [var1.ordinal ()]) {caso 1: return 1; caso 2: retorno 2; predeterminado: return 3; }} public int enum1Switch (Sex1Enum var1) {switch (1.S witch M ap SwitchMapEjemplo de ejemplo de S w i t c h M a p come x a m p l e pruebaexprést e s t Sex1Enum [var1.ordinal ()]) {caso 1: retorno 1; caso 2: retorno 2; predeterminado: retorno 3;}}} Copiar código
3. ¿Cómo se convirtió el tipo de cadena en tipo int?
En primer lugar, primero sabemos cómo el tipo char se convierte en el tipo int. Es muy simple, es un código ASCII. Por ejemplo, hay una declaración switch:
public int charSwitch (char c) {switch © {case'a ': return 1; case'b': return 2; default: return Integer.MAX_VALUE;}} Copia el código
Resultado de descompilación:
public int charSwitch (char var1) {switch (var1) {case 97: return 1; case 98: return 2; default: return Integer.MAX_VALUE;}} Copiar código
Entonces, para String, se usa la función hashCode (), pero dos cadenas diferentes hashCode () pueden ser iguales, entonces se requiere la función equals (), por ejemplo, hay es una declaración de cambio:
public int stringSwitch (String ss) {switch (ss) {case “ABCDEa123abc”: return 1; case “ABCDFB123abc”: return 2; case “helloWorld”: return 3; default: return Integer.MAX_VALUE;}} Copia los
caracteres en el código Los hashCodes de las cadenas ABCDEA123abc y ABCDFB123abc son iguales, el resultado de la descompilación es:
public int stringSwitch (String var1) {byte var3 = -1; switch (var1.hashCode ()) {case -1554135584: if (var1. equals ("helloWorld")) {var3 = 2;} break; case 165374702: if (var1.equals ("ABCDFB123abc")) {var3 = 1;} else if (var1.equals ("ABCDEa123abc")) {var3 = 0;}} switch (var3) {case 0: return 1; case 1: return 2; case 2: return 3; default: return Integer.MAX_VALUE;}} Copia el código y
puedes ver que introduce la variable local var3 Para el hashCode igual, pase el juicio del método equals () y, finalmente, juzgue el valor de var3.
4. ¿Su tipo de empaque es compatible?
Tome el tipo Integer como ejemplo. Carácter y Byte son lo mismo. Por ejemplo, hay una instrucción de cambio:
public int integerSwitch (Integer c) {switch © {case 1: return 1; case 2: return 2;} return -1;} Copiar el código El
resultado de la descompilación es:
public int integerSwitch (Integer var1) {switch (var1. intValue ()) {caso 1: retorno 1; caso 2: retorno 2; predeterminado: retorno -1;}} Copiar el código Como
puede ver, el tipo de paquete es compatible, lo que se resuelve mediante unboxing automático.
¿Qué pasa si el tipo de empaquetado es NULL? Primero que nada, sabemos que el caso de swtich no agrega null, y la compilación falla ¿Qué pasa si pasa null?
La respuesta es NPE, después de todo, en realidad es el desempaquetado del tipo de empaque, y naturalmente reportará un puntero nulo.
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/dcj19980805/article/details/115004804
Recomendado
Clasificación