J'ai une question folle sur les commutateurs Java.
int key = 2;
switch (key) {
case 1:
int value = 1;
break;
case 2:
value = 2;
System.out.println(value);
break;
default:
break;
}
Scénario 1 - Lorsque le key
est deux , il imprime avec succès la valeur 2.
Scénario 2 - Quand je vais commenter value = 2
dans case 2:
ce gloussements dire la La valeur variable locale peut ne pas avoir été initialisé .
Questions:
Scénario 1: Si le flux d'exécution ne va pas à case 1:
(quand le key = 2
), alors comment connaît-il le type de la variable de valeur int
?
Scénario 2: Si le compilateur connaît le type de la variable de valeur comme int
, alors il doit avoir accédé à l' int value = 1;
expression dans case 1:
. (Déclaration et initialisation). Alors pourquoi est - ce sqawrk Quand je vais commenter value = 2
en case 2:
disant la La valeur variable locale peut ne pas avoir été initialisé .
java
scope
initialization
switch-statement
declaration
Namalfernandolk
la source
la source
Réponses:
Les instructions de commutation sont étranges en termes de portée, en gros. À partir de la section 6.3 du JLS :
Dans votre cas,
case 2
est dans le même bloc quecase 1
et apparaît après, même sicase 1
elle ne s'exécutera jamais ... donc la variable locale est dans la portée et disponible pour l' écriture même si vous n'avez logiquement jamais "exécuté" la déclaration. (Une déclaration n'est pas vraiment "exécutable" bien que l'initialisation le soit.)Si vous commentez l'
value = 2;
affectation, le compilateur sait toujours à quelle variable vous faites référence, mais vous n'aurez parcouru aucun chemin d'exécution qui lui attribue une valeur, c'est pourquoi vous obtenez une erreur comme vous le feriez lorsque vous essayez de lire toute autre variable locale non attribuée de manière définitive.Je vous recommande fortement de ne pas utiliser de variables locales déclarées dans d'autres cas - cela conduit à un code très déroutant, comme vous l'avez vu. Lorsque j'introduis des variables locales dans des instructions switch (ce que j'essaie de faire rarement - les cas devraient être très courts, idéalement), je préfère généralement introduire une nouvelle portée:
Je pense que c'est plus clair.
la source
La variable a été déclarée (en tant qu'int), mais pas initialisée (une valeur initiale lui a été attribuée). Pensez à la ligne:
Comme:
La
int value
partie indique au compilateur au moment de la compilation que vous avez une variable appelée value qui est un int. Lavalue = 1
partie l'initialise, mais cela se produit au moment de l'exécution et ne se produit pas du tout si cette branche du commutateur n'est pas entrée.la source
Depuis http://www.coderanch.com/t/447381/java-programmer-SCJP/certification/variable-initialization-within-case-block
la source
Avec l'intégration de JEP 325: Switch Expressions (Preview) dans les versions d'accès anticipé JDK-12. Il y a certains changements qui pourraient être vus de la réponse de Jon -
Portée de la variable locale - Les variables locales dans les cas de commutation peuvent désormais être locales au cas lui-même au lieu de l'ensemble du bloc de commutation . Un exemple (similaire à ce que Jon avait tenté syntaxiquement également) considérant la
Day
classe enum pour plus d'explications:Switch Expressions - Si l'intention est d'attribuer une valeur à une variable puis de l'utiliser, une fois peut utiliser les expressions switch. par exemple
la source
Cette explication pourrait vous aider.
la source
Spécification Java:
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.11
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.7
Déclarations étiquetées:
En d'autres termes, le cas 1, le cas 2 sont des étiquettes dans l'instruction switch. Les instructions break et continue peuvent être appliquées aux étiquettes.
Étant donné que les étiquettes partagent la portée de l'instruction, toutes les variables définies dans les étiquettes partagent la portée de l'instruction switch.
la source