public class Test2 {
/*
* Cette "variable" est d'un type particulier. Puisqu'il s'agit d'une
* constante (une variable qui ne peut changer de valeur), le compilateur
* s'autorise à ne jamais faire référence à cette variable comme d'ordinaire
* mais à en oublier le contenant pour ne plus utiliser que le contenu qui
* réside alors, à chaque utilisation, dans le code.
*/
public static final int C = 100;
/*
* Cette variable a aussi un statut particulier. Elle préexiste avant l'appel
* à main et réside donc dans une zone particulière, la zone des
* variables statiques, distincte de la pile et du tas.
*/
public static int v = 777;
/*
* Le passage d'argument est effectué par valeur. La variable x n'a rien
* de particulier, concernant son existence, par rapport à la variable
* locale y. Toutes les deux sont locales et résident dans la pile.
* La différence réside dans l'initialisation, opération dans laquelle
* le paramètre x est initialisé lors de l'appel à la fonction avec la
* valeur du paramètre transmis. Les deux variables résident dans la pile.
* Les variables locales sont créés lors de chaque appel à la fonction et
* disparraissent lorsque le contrôle sort de la fonction.
*/
public static void f(int x) {
int y = 10;
System.out.println(x);
System.out.println(v);
x = 9999;
System.out.println("dans f() "+x);
}
/* Le passage d'argument est aussi par valeur (ou copie). On créé la variable
* locale t initialisée avec la valeur du paramètre fourni à l'appel. La
* différence réside dans le fait que l'objet qui est pointé par t est lui
* "global" car son existence n'est pas liée à l'appel de cette fonction (a
* priori), il existe par ailleurs (dans le tas) et est manipulé via une
* nouvelle référence temporaire. Bien entendu toute modification de l'objet
* pointé est visible par ailleurs...
*/
public static void f(int []t) {
System.out.println(t[0]);
t[0] = 8888;
System.out.println(t[0]);
}
/*
* On peut donc dire enfin que main est une fonction comme une autre, elle
* n'a aucune particularité en tant que fonction. La seule particularité
* est celle de l'exécution des programmes qui commencent toujours (a priori)
* par un appel initia à main.
*/
public static void main(String []args) {
System.out.println(args[0]);
/*
* Deux références vers un même objet. La modification du tableau via
* l'une est visible de l'autre évidemment.
*/
int []t = new int[5];
int []t2;
t2 = t;
t[0] = 333;
System.out.println(t[0]);
System.out.println(t2[0]);
// L'objet est recyclé lrosque les deux références ne pointent plus vers
// l'objet.
/*
t = null;
System.out.println(t2[0]);
t2 = null;
*/
int a = 666+C;
int b = 766;
/*
* L'égalité est celle des valeurs de la variable. Pas de particularité
* pour les types primitifs.
*/
if (a==b) { System.out.println("vrai"); }
else { System.out.println("faux"); }
/*
* Ici c'est la même chose. On compare le contenu des références, par
* conséquent on teste si les deux références désignent ou non le
* même objet.
*/
if (t==t2) { System.out.println("vrai"); }
else { System.out.println("faux"); }
t2 = new int[5];
t2[0] = 333;
if (t==t2) { System.out.println("vrai"); }
else { System.out.println("faux"); }
/*
* Un appel effectué avec la valeur de la variable a à ce moment.
*/
f(a);
System.out.println("apres f() "+a);
/*
* Un appel effectué avec une constante. On ne passe pas un lvalue...
*/
f(500);
/*
* On passe la valeur de la référence. L'objet peut être modifié par
* la fonction et l'effet est visible. Mais il est impossible que la
* fonction modifie t elle-même.
*/
f(t);
System.out.println("apres f() "+t[0]);
/*
* Les tableaux à deux dimensions n'en sont pas. Il s'agit de référence
* vers un tableau de références vers des tableaux d'entiers.
*/
int [][]tab = new int[3][5];
tab[0][3];
}
}