Pourquoi les variables locales, y compris les primitives, doivent-elles toujours être initialisées en Java?

Pourquoi les variables locales, y compris les primitives, doivent-elles toujours être initialisées en Java? Pourquoi est-ce que la même chose n’est pas applicable dans le cas des variables d’instance?

Il y avait une question à ce sujet très récemment pour C # … – lisez les réponses là aussi, car c’est fondamentalement la même chose. Vous pouvez également trouver le récent article de blog d’Eric Lippert intéressant; c’est au moins autour du même secteur, même si sa poussée est quelque peu différente.

Fondamentalement, exiger une valeur pour qu’une valeur soit atsortingbuée avant de la lire est une bonne chose. Cela signifie que vous ne lirez pas accidentellement quelque chose que vous n’aviez pas l’intention de faire. Oui, les variables peuvent avoir des valeurs par défaut – mais n’est-il pas mieux pour le compilateur de pouvoir attraper votre bogue à la place, s’il peut prouver que vous essayez de lire quelque chose qui n’a peut-être pas encore été atsortingbué? Si vous voulez donner à une variable locale une valeur par défaut, vous pouvez toujours l’assigner explicitement.

Maintenant, ça va pour les variables locales – mais par exemple et les variables statiques, le compilateur n’a aucun moyen de connaître l’ordre dans lequel les méthodes seront appelées. Une propriété “setter” sera-t-elle appelée avant le “getter”? Il n’a aucun moyen de savoir, il n’a donc aucun moyen de vous alerter sur le danger. C’est pourquoi les valeurs par défaut sont utilisées pour les variables d’instance / statiques – au moins, vous obtiendrez une valeur connue (0, false, null, etc.) au lieu de simplement “ce qui s’est passé en mémoire à ce moment”. (Cela supprime également le problème de sécurité potentiel lié à la lecture de données sensibles qui n’ont pas été explicitement effacées.)

Eh bien, dans le cas d’une variable locale, il est clair que cela signifie «avant» puisque le stream de programme entre la déclaration (dans la méthode) et la référence est séquentiel. Dans le cas de champs déclarés en dehors de la méthode, le compilateur ne sait jamais quel code va être utilisé alors qu’il ne peut pas générer d’erreur, car une autre méthode est susceptible d’initialiser le champ avant son utilisation.

En Java, les variables de classe et d’instance prennent une valeur par défaut (null, 0, false) si elles ne sont pas initialisées manuellement. Cependant, les variables locales n’ont pas de valeur par défaut. À moins qu’une variable locale n’ait été assignée à une valeur, le compilateur refusera de comstackr le code qui le lira. IMHO, cela conduit à la conclusion, que l’initialisation d’une variable locale avec une valeur par défaut (comme null, ce qui pourrait conduire à une NullPointerException plus tard) quand il est déclaré est en réalité une mauvaise chose. Prenons l’exemple suivant:

Object o; if () o = ; else o = ; System.out.println(o); 

Une initialisation de o avec null est complètement inutile, car le compilateur Java vérifie au moment de la compilation que tout chemin de code initialise o (avec une valeur nulle ou non nulle) avant la lecture de la variable. Cela signifie que le compilateur refusera de comstackr la ligne System.out.println(o); Si vous souhaitez commenter l’une des deux initialisations de la variable o dans l’extrait de code ci-dessus.

Cela vaut pour Java, et peut-être uniquement pour Java. Je ne connais pas le langage comme C #. Dans le bon vieux C (et peut-être même C ++), il est toujours recommandé d’initialiser toujours les variables lors de leur déclaration, AFAIK. De tels langages de programmation “anciens” pourraient être la raison pour laquelle la recommandation d’initialiser toujours les variables apparaît dans les livres et les discussions sur les langages modernes comme Java, où la compilation vérifie si une variable a été initialisée ou non.

Pas totalement vrai. Les variables locales doivent seulement être initialisées si elles sont la référence. Une variable locale peut être laissée non initialisée si elle n’est jamais référencée. Par exemple:

 int x; // Valid int y; println("y=" + y); // Not valid since y's value has never been assigned 

Les variables locales et les primitives doivent être initialisées avant utilisation car vous sauriez à quoi s’attendre des valeurs. Historiquement, quand une nouvelle variable était créée, elle contiendrait des valeurs aléatoires de la mémoire [et on ne pouvait pas prédire la valeur]. Java en a également besoin car cela empêche la présence de variables orphelines.

En pratique, toutes les variables doivent être initialisées avant de les utiliser.

Je ne peux pas penser à une fois où vous voudriez utiliser une variable avant de définir sa valeur (à moins de la comparer à null).

Il est nécessaire d’initialiser les variables locales (uniquement lorsque nous les utilisons) car elles n’obtiennent aucune valeur par défaut comme les variables d’instance.

Et comme règle de base, nous devrions toujours initialiser toute variable avant de l’utiliser. Sinon, cela peut entraîner une erreur comme nullPointer, etc.

Maintenant, pourquoi les variables locales ne reçoivent-elles pas la valeur par défaut? La raison en est que les variables locales résident sur la stack et ne sont visibles que dans le contexte de la méthode locale, contrairement aux variables d’instance qui résident sur le tas et ont une scope dans tout le programme.

Donc, lorsque la stack se terminera, la valeur de la méthode locale sera également détruite: 1] Ils sont supposés être initialisés explicitement (quand on les utilise) 2] Ils ne doivent pas être initialisés implicitement (par null, 0 ou faux) comme des variables d’instance