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]; } }