Je me demande simplement pourquoi l' switch
instruction Java 7 ne prend pas en charge un null
cas et jette à la place NullPointerException
? Voir la ligne commentée ci-dessous (exemple tiré de l'article Tutoriels Java surswitch
):
{
String month = null;
switch (month) {
case "january":
monthNumber = 1;
break;
case "february":
monthNumber = 2;
break;
case "march":
monthNumber = 3;
break;
//case null:
default:
monthNumber = 0;
break;
}
return monthNumber;
}
Cela aurait évité une if
condition de vérification nulle avant chaque switch
utilisation.
java
switch-statement
language-design
Prashant Bhate
la source
la source
null
provoquera une exception. Effectuez uneif
vérificationnull
, puis entrez dans laswitch
déclaration.NullPointerException
si l'expression évalue ànull
au moment de l'exécution] est un meilleur résultat que de sauter silencieusement toute l'instruction switch ou de choisir d'exécuter les instructions (le cas échéant) après le étiquette par défaut (le cas échéant).Réponses:
Comme le souligne damryfbfnetsi dans les commentaires, JLS §14.11 contient la note suivante:
(c'est moi qui souligne)
Si la dernière phrase fait abstraction de la possibilité d'utilisation
case null:
, elle semble raisonnable et offre un aperçu des intentions des concepteurs de langage.Si nous regardons plutôt les détails de la mise en œuvre, ce billet de blog de Christian Hujer contient des spéculations perspicaces sur les raisons pour lesquelles les
null
commutateurs ne sont pas autorisés (bien qu'il se concentre sur leenum
commutateur plutôt que sur leString
commutateur):Bien que les
String
commutateurs soient implémentés différemment , leenum
commutateur est venu en premier et a établi le précédent pour la façon dont la commutation sur un type de référence devrait se comporter lorsque la référence estnull
.la source
case null:
si elle avait été implémentée exclusivement pourString
. Actuellement, touteString
vérification nécessite de toute façon une vérification nulle si nous voulons le faire correctement, bien que la plupart du temps implicitement en mettant la constante de chaîne en premier comme dans"123test".equals(value)
. Maintenant, nous sommes obligés d'écrire notre déclaration de commutation comme dansif (value != null) switch (value) {...
En général, il
null
est désagréable à manipuler; peut-être qu'une meilleure langue peut vivre sansnull
.Votre problème peut être résolu par
la source
month
s'agit d'une chaîne vide: cela la traitera de la même manière qu'une chaîne nulle.Ce n'est pas joli, mais
String.valueOf()
vous permet d'utiliser une chaîne nulle dans un commutateur. S'il trouvenull
, il le convertit en"null"
, sinon il renvoie simplement la même chaîne que vous l'avez passé. Si vous ne gérez pas"null"
explicitement, alors il ira àdefault
. La seule mise en garde est qu'il n'y a aucun moyen de faire la distinction entre la chaîne"null"
et unenull
variable réelle .la source
Ceci est une tentative de répondre pourquoi il jette
NullPointerException
La sortie de la commande javap ci-dessous révèle que le
case
choix est basé sur le hashcode de laswitch
chaîne d'argument et, par conséquent, lève NPE lorsqu'il.hashCode()
est appelé sur une chaîne nulle.Cela signifie que, sur la base des réponses au hashCode de Java, peut-il produire la même valeur pour différentes chaînes? , bien que rare, il est toujours possible que deux cas soient mis en correspondance (deux chaînes avec le même code de hachage) Voir cet exemple ci-dessous
javap pour lequel
Comme vous pouvez le voir, un seul cas est généré pour
"Ea"
et"FB"
mais avec deuxif
conditions pour vérifier la correspondance avec chaque chaîne de cas. Manière très intéressante et compliquée d'implémenter cette fonctionnalité!la source
hashCode
renvoi des mêmes valeurs sur différentes exécutions d'un programme, mais puisque les hachages de chaîne sont intégrés dans des exécutables par le compilateur, la méthode de hachage de chaîne finit par faire partie de la spécification du langage.Longue histoire courte ... (et j'espère assez intéressante !!!)
Les Enum ont été introduits pour la première fois dans Java1.5 ( Sep'2004 ) et le bogue demandant d' autoriser le basculement sur String a été déposé depuis longtemps ( Oct'95 ). Si vous regardez le commentaire publié sur ce bogue en juin 2004 , il
Don't hold your breath. Nothing resembling this is in our plans.
semble qu'ils ont différé ( ignoré ) ce bogue et ont finalement lancé Java 1.5 la même année où ils ont introduit 'enum' avec un ordinal commençant à 0 et ont décidé ( manqué ) pour ne pas prendre en charge null pour enum. Plus tard dans Java1.7 ( juillet 2011 ), ils ont suivi ( forcé) la même philosophie avec String (c'est-à-dire lors de la génération du bytecode, aucune vérification de null n'a été effectuée avant d'appeler la méthode hashcode ()).Donc, je pense que cela se résume au fait que l'énumération est arrivée en premier et a été implémentée avec son ordinal commençant à 0 en raison de laquelle ils ne pouvaient pas prendre en charge la valeur nulle dans le bloc de commutation et plus tard avec String, ils ont décidé de forcer la même philosophie, c'est-à-dire que la valeur nulle n'est pas autorisé dans le bloc de commutation.
TL; DR Avec String, ils auraient pu prendre soin de NPE (causé par une tentative de génération de hashcode pour null) tout en implémentant le code java en conversion de code d'octet, mais ont finalement décidé de ne pas le faire.
Réf: TheBUG , JavaVersionHistory , JavaCodeToByteCode , SO
la source
Selon Java Docs:
Puisque
null
n'a aucun type et n'est une instance de rien, cela ne fonctionnera pas avec une instruction switch.la source
null
est une valeur valide pour unString
,Character
,Byte
,Short
ouInteger
référence.La réponse est simplement que si vous utilisez un commutateur avec un type de référence (tel qu'un type primitif encadré), l'erreur d'exécution se produira si l'expression est nulle car le déballage lèverait le NPE.
donc case null (ce qui est illégal) ne pourrait jamais être exécuté de toute façon;)
la source
if (x == null) { // the case: null part }
Je suis d'accord avec les commentaires perspicaces (Sous le capot ....) dans https://stackoverflow.com/a/18263594/1053496 dans la réponse de @Paul Bellora.
J'ai trouvé une autre raison de mon expérience.
Si 'case' peut être null, cela signifie que le commutateur (variable) est nul, tant que le développeur fournit un cas 'nul' correspondant, nous pouvons affirmer que tout va bien. Mais que se passera-t-il si le développeur ne fournit pas de cas «nul» correspondant. Ensuite, nous devons le faire correspondre à un cas «par défaut» qui peut ne pas être ce que le développeur a prévu de gérer dans le cas par défaut. Par conséquent, faire correspondre «null» à une valeur par défaut pourrait provoquer un «comportement surprenant». Par conséquent, lancer 'NPE' obligera le développeur à gérer explicitement tous les cas. J'ai trouvé que lancer du NPE dans ce cas était très réfléchi.
la source
Utiliser la classe Apache StringUtils
la source