La portée d'une variable désigne les parties du code source où elle est utilisable. Ce peut être par exemple, le projet entier, le fichier dans lequel la variable est déclarée, ou simplement une partie spécifique de ce fichier.
Dans ce cours nous utiliserons le terme de variable globale pour désigner une variable dont la portée est celle du fichier où elle est déclarée.
Inversement, nous dirons qu'une variable est locale si sa portée se restreint à une partie seulement du fichier où elle est déclarée.
En Java, une manière d'obtenir une variable globale est de la déclarer dans la zone de déclaration que nous avons définie dans le cours précédent.
Jusqu'à présent toutes les variables que vous avez utilisées dans les exercices de ce cours sont donc des variables globales: elles peuvent être utilisées dans tout le fichier source.
Pour obtenir une variable locale, il faut la déclarer à l'intérieur d'un sous-programme.
Pour l'instant, nous n'avons pas défini ce qu'est un sous-programme de manière générale. Par contre, vous connaissez les procédures évènementielles qui représentent une catégorie particulière de sous-programme.
Nous allons donc, pour l'instant, baser nos explications concernant la portée des variables en utilisant uniquement les procédures évènementielles. Gardez toutefois à l'esprit que ces explications seront valables pour n'importe quel type de sous-programme.
Pour illustrer la différence entre une variable locale et une variable globale, nous commencerons par quelques exemples de programmes.
Ces différents exemples de programmes se trouvent dans le répertoire Java-Exemple-Sous-Programme. Vous pouvez donc les ouvrir et les exécuter pour vous aider à mieux comprendre.
Cet exemple ce trouve dans le dossier:
Exemple-Java-Sous-Programme/Global
Voici le formulaire du programme:
et voici un extrait du code de ce programme:
public class Global ... { int x; .... private void BT_AffecterActionPerformed (...) { x = 1961; } private void BT_AfficherActionPerformed(...) { es.Afficher(x, CT_X); }
Dans ce premier exemple, la variable x est déclarée à l'extérieur de tout sous-programme. Il s'agit donc d'une variable globale.
Cela a les conséquences suivantes:
Cet exemple ce trouve dans le dossier:
Exemple-Java-Sous-Programme/Local0
Nous déclarons cette fois-ci la variable x à l'intérieur de la procédure BT_AffecterActionPerformed. On constate alors que le projet n'est pas compilable. Le compilateur java détecte une erreur :
Cette erreur est localisée dans l'instruction es.Afficher(x, CT_X) de la procédure BT_AfficherActionPerformed.
Comment expliquer cette erreur ?
Le problème vient du fait qu'une variable locale n'est accessible qu'à l'intérieur du sous-programme où elle est déclarée. Autrement dit, la portée d'une variable locale est limitée à ce sous-programme.
Dans notre exemple, x n'est donc définie qu'à l'intérieur de la procédure BT_AffecterActionPerformed et nul part ailleurs.
Cet exemple ce trouve dans le dossier:
Exemple-Java-Sous-Programme/Local1
Il s'agit d'une version légèrement modifiée du programme précédent, dans laquelle la variable x est déclarée dans la zone de déclaration ainsi qu'à l'intérieur de la procédure BT_AffecterActionPerformed:
public class Local1 ... { int x = 1935; ..... private void BT_AffecterActionPerformed(...) { int x = 1961; } private void BT_AfficherActionPerformed(...) { es.Afficher(x, CT_X); }
Cet exemple ne provoque aucun message d'erreur.
Vous vous demandez peut-être comment une telle chose est possible, car a priori une variable ne peut pas être déclarée deux fois. On devrait avoir un message d'erreur. Or il n'en est rien !
En réalité, il y a deux variables distinctes: la variable x déclarée en global et celle déclarée en local dans la procédure BT_AffecterActionPerformed.
Bien qu'elles portent le même nom, ces deux variables sont totalement indépendantes.
Mais si le compilateur java rencontre une instruction utilisant x, comment peut-il savoir de quelle variable il s'agit ?
Il s'en sort de la manière suivante:
De manière générale:
Autrement dit, si une variable globale est redéclarée à l'intérieur de certains sous-programmes alors:
A présent, faites l'expérience suivante:
Comment expliquer ceci ?
Lorsque vous lancez le programme, la JVM affecte la valeur 1935 à la variable x déclarée en globale. Lorsque vous cliquez ensuite sur le bouton Afficher X, elle exécute la procédure BT_AfficherActionPerformed dans laquelle ne figure aucune déclaration locale de la variable x. Cette procédure affiche donc la valeur de la variable globale x qui vaut 1935.
Lorsque vous cliquez sur le bouton Affecter la valeur 1961 à X, elle exécute la procédure BT_AffecterActionPerformed dans laquelle x est déclarée en local. Cette même procédure affecte la valeur 1961 à x. Mais comme x est déclarée dans cette procédure, cette affectation agit sur la variable x déclarée dans cette procédure et non pas sur la variable x déclarée en global.
Enfin, lorsque vous recliquez sur le bouton Afficher X, il exécute la procédure BT_AfficherActionPerformed dans laquelle ne figure aucune déclaration locale de la variable x. Cette procédure affiche donc la valeur de la variable globale x qui est toujours égale à 1935.
Par contre:
Durant l'exécution d'un programme, une variable locale peut donc avoir plusieurs vies: elle renait chaque fois que le sous-programme contenant sa déclaration s'exécute et meurt chaque fois qu'il se termine.
Avec les variables locales, il devient de possible de déclarer plusieurs fois une variable de même nom.
Si une "même" variable est déclarée en local et en global (voir exemple3):
Nous n'avons pas présenté d'exemple de ce type, mais il est également possible de déclarer plusieurs variables de même nom dans des sous-programmes distincts. Tout se passe alors comme si on avait donné des noms de variables distincts pour ces différentes déclarations. Autrement dit: