Java Switch et String sont bons

Nous savons que Java Switch prend en charge les types byte, short et int. Dans JDK 1.5, les types d'énumération étaient pris en charge, et dans JDK 1.7, les types String étaient pris en charge. Alors pourquoi ne peut-il pas prendre en charge le type long? De toute évidence, il s'agit d'un type numérique comme byte, short et int, alors pourquoi prend-il en charge le type String?
1. Conclusions
Parlons d'abord de la conclusion: la
couche inférieure du commutateur utilise le type int pour faire des jugements. Même l'énumération et les types String sont finalement transformés en type int. Étant donné que le type long indique que la plage est supérieure au type int, le type long n'est pas pris en charge.
Ce qui suit est une description détaillée de la façon dont chaque type est converti en un type int. La commande de compilation utilisée est javac et le site Web de décompilation est: javare.cn
2. Comment le type d'énumération est-il devenu le type int?
Avant l'expérience, je tenais pour acquis qu'il était calculé en fonction du champ de type int de l'énumération (car l'énumération générale est un type int et un type chaîne), mais après une autre réflexion, au cas où l'énumération n'aurait pas de Champs de type int, au cas où il y aurait plusieurs champs int, donc ce n'est certainement pas le cas, voyons l'expérience ci-dessous.
Définissez deux classes d'énumération, une classe d'énumération a un attribut de type int et un attribut de type chaîne, et l'autre classe d'énumération n'a qu'un seul attribut de chaîne:
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;}} Copiez le code
et écrivez une classe de test, puis créez two Les valeurs de retour correspondantes FEMALE et MALE d'un commutateur d'énumération sont différentes:
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;}}} Copiez le code
Décompilez ces classes:
// SexEnum.class public enum SexEnum {MALE (1, “鐢 ”), FEMALE (0, “濂 ”); private int type; private String name; // $ FF: champ synthétique private static final SexEnum [] $ VALUES = new SexEnum [] {MALE, FEMALE}; private SexEnum (int var3, String var4) {this.type = var3; this.name = var4;}} // Sex1Enum.class public enum Sex1Enum {MALE ("鐢 ”), FEMALE (“ 濂 ”); private String name; // $ FF: champ synthétique private static final Sex1Enum [] $ VALUES = new Sex1Enum [] {MALE, FEMALE}; private Sex1Enum (String var3) {this .name = var3;}} Copiez le code
Décompilez ces deux classes d'énumération et trouvez qu'il existe un tableau $ VALUES supplémentaire, qui contient toutes les valeurs d'énumération. Continuez à décompiler la classe de test:
// SwitchTest $ 1.class import com.example.express.test.Sex1Enum; import com.example.express.test.SexEnum; // $ FF: classe de classe synthétique SwitchTest $ 1 {// $ FF : champ synthétique statique final int [] S witch M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpresst e s t SexEnum; // $ FF: champ synthétique statique final int []S witch M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpresst e s t Sex1Enum = new int [Sex1Enum.values ​​(). length]; statique {essayez {S witch M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpresst e s t Sex1Enum [Sex1Enum.FEMALE.ordinal ()] = 1; } catch (NoSuchFieldError var4) {; } essayez {S witch M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpresst e s t Sex1Enum [Sex1Enum.MALE.ordinal ()] = 2; } catch (NoSuchFieldError var3) {; }S sorcière M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpresst e s t SexEnum = new int [SexEnum.values ​​(). length]; essayez {S witch M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpresst e s t SexEnum [SexEnum.MALE.ordinal ()] = 1; } catch (NoSuchFieldError var2) {; } essayez {S witch M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpressT E S T SexEnum [SexEnum.FEMALE.ordinal ()] = 2;} le catch (NoSuchFieldError var1) {;}}} copie le code
généré en première classe appelé link SwitchTest $ 1.java dont définit deux morceaux Par exemple, l'ordre d'ajout des deux éléments du tableau est exactement le même que l'ordre d'appel de la classe de commutation dans la classe de test.
Insérez la description de l'image ici

L'indice de l'élément d'énumération dans le tableau est déterminé par la fonction ordinal (), qui renvoie le numéro ordinal de l'élément d'énumération dans la classe d'énumération.
Ici, nous savons déjà que dans l'instruction switch, l'élément d'énumération est converti en type int selon le numéro de séquence de l'élément d'énumération dans l'énumération. Enfin, regardez le résultat de la décompilation de la classe de test pour vérifier:
// SwitchTest.class import com.example.express.test.Sex1Enum; import com.example.express.test.SexEnum; import com.example.express.test. SwitchTest .1; public class SwitchTest {public int enumSwitch (SexEnum var1) {switch (1. S witch M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpresst e s t SexEnum [var1.ordinal ()]) {cas 1: retour 1; cas 2: retour 2; par défaut: retourne 3; }} public int enum1Switch (Sex1Enum var1) {switch (1.S witch M ap SwitchMapExemple d'exemple S w i t c h M a p come x a m p l e test de testexpresst e s t Sex1Enum [var1.ordinal ()]) {case 1: return 1; case 2: return 2; default: return 3;}}} Copier le code
3. Comment le type String est-il devenu le type int?
Tout d'abord, nous savons comment le type char devient le type int. C'est très simple, c'est un code ASCII. Par exemple, il y a une instruction switch:
public int charSwitch (char c) {switch © {case'a ': return 1; case'b': return 2; default: return Integer.MAX_VALUE;}} Copier le code
Résultat de la décompilation:
public int charSwitch (char var1) {switch (var1) {case 97: return 1; case 98: return 2; default: return Integer.MAX_VALUE;}} Copier le code
Donc pour String, la fonction hashCode () est utilisée, mais deux chaînes différentes hashCode () peuvent être égales, alors la fonction equals () est requise, par exemple, là est une instruction switch:
public int stringSwitch (String ss) {switch (ss) {case «ABCDEa123abc»: return 1; case «ABCDFB123abc»: return 2; case «helloWorld»: return 3; default: return Integer.MAX_VALUE;}} Copiez les
caractères dans le code Les hashCodes des chaînes ABCDEA123abc et ABCDFB123abc sont égaux, le résultat de la décompilation est:
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;}} Copiez le code et
vous pouvez voir qu'il introduit la variable locale var3 Pour le hashCode égal, passez le jugement de la méthode equals () et enfin jugez la valeur de var3.
4. Leur type d'emballage est-il pris en charge?
Prenons le type Integer comme exemple. Le caractère et l'octet sont identiques. Par exemple, il existe une instruction switch:
public int integerSwitch (Integer c) {switch © {case 1: return 1; case 2: return 2;} return -1;} Copier le code Le
résultat de la décompilation est:
public int integerSwitch (Integer var1) {switch (var1. intValue ()) {case 1: return 1; case 2: return 2; default: return -1;}} Copier le code Comme
vous pouvez le voir, le type de package est pris en charge, ce qui est résolu par unboxing automatique.
Que faire si le type d'empaquetage est NULL? Tout d'abord, nous savons que le cas de swtich n'ajoute pas de null et que la compilation échoue. Que faire si vous passez null?
La réponse est NPE, après tout, c'est en fait le déballage du type d'emballage, et il rapportera naturellement un pointeur nul.
Insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/dcj19980805/article/details/115004804
conseillé
Classement