TP de Java Introduction au Langage _____________________ Sujets abordés dans ce TP : Dans votre répertoire source, le compilateur a créé un fichier (App.class). Ce fichier correspond à votre exécutable Java, c’est le « binaire » (ou byte code) utilisé par la machine virtuelle Java pour exécuter votre programme. Premières notions de P.O.O Premier programme Premières notions de P.O.O Types primitifs de données Opérateurs Instructions de contrôle Tableaux Chaînes de caractères Algorithmes de tri 1) Introduction Java est un langage de P.O.O (Programmation Orientée Objets). La programmation Java est donc basée sur la manipulation d’objets composés de données membres et de méthodes. Les objets sont des instances de classes. La classe correspond à la généralisation de type, une classe est une description d’un ensemble d’objets ayant une structure de données commune et disposant des mêmes méthodes. Premier programme Ecrire le programme suivant, enregistrer le dans un fichier (App.java), compiler le à l’aide de votre environnement de programmation, puis exécuter le. Vous pouvez également utiliser la commande « javac App.java » pour la compilation du fichier suivie de la commande « java –cp .\ App » pour son exécution. class App { public static void main(String args[]) { System.out.println("Hello World"); } } App correspond ici à votre classe, et main la fonction d’exécution principale de cette classe. L’appel de la fonction System.out.println correspond au printf en C et cout en C++. La déclaration static et public sont des obligations indispensables pour l’appel de la fonction main. Cette déclaration vous oblige également de déclarer votre classe App contenant le main dans un fichier de même nom (App.java). On admettra dans ce TP ces différentes notions, elles seront abordées plus en détails dans les TP suivants. Reprendre votre programme de la façon suivante : class HelloWorld { void sayHello() { System.out.println("Hello World"); } } class App { public static void main(String args[]) { HelloWorld my = new HelloWorld(); my.sayHello(); } } Vous avez défini ici votre première classe HelloWorld, et sa méthode sayHello(). my correspond à votre premier objet instance de la classe HelloWorld, alloué suite à l’appel de l’opérateur new. La notion d’opérateur est abordée plus tard dans ce TP. La méthode sayHello() est appelé via l’opérateur point ., tel que my.sayHello(). Reprendre la classe HelloWorld de la façon suivante : /** * HelloWorld */ class HelloWorld { //hello member String hello = "Hello World"; /** * sayHello */ void sayHello() { System.out.println(hello); } } Vous avez ici défini votre première donnée membre hello de votre classe HelloWorld de type String. Sur cet exemple, des commentaires ont été rajoutés de type ligne // et bloc /** */. 1 A travers ce court exemple, vous avez vu les principes de base de la P.O.O, la classe HelloWorld, sa méthode sayHello et sa donnée membre hello, et l’objet my instance de la classe HelloWorld alloué suite à l’appel de l’opérateur new. Conditionnel Allocation Point Instructions de contrôles Remarque : La classe HelloWorld a été définie de façon Majuscule-Majuscule, et la méthode sayHello de façon minuscule-Majuscule. C’est une convention de programmation implicite en Java. Remarque : Prenez l’habitude de programmer en « anglais », et de commenter vos programmes à la manière de cet exemple. En effet, le code et les commentaires formatés ainsi peuvent être traités par la suite par l’outil de documentation automatique de code javadoc. Continuer cet exemple en « déplaçant » la déclaration de la classe HelloWorld dans un fichier (TPIntro.java), recompiler le tout, puis exécuter votre programme à partir du fichier (App.java). Supprimer ensuite le fichier (TPIntro.java), sans supprimer le fichier (HelloWorld.class) du répertoire local, recompiler l’ensemble. Supprimer ensuite le fichier (HelloWorld.class) du répertoire local et recompiler l’ensemble, commenter. Vous voyez dans cet exemple qu’il n’est pas nécessaire d’avoir les sources correspondantes aux définitions des classes pour les exploiter. Durant la compilation d’un fichier source, les (.class) des classes utilisées dans ce fichier source sont recherchées dans le répertoire local par le compilateur. Ceci fait que vous avez toujours un ordonnancement à respecter pour la compilation de différents fichiers. Remarque : Vous pouvez également utiliser la commande « javac *.java » pour la compilation de l’ensemble des fichiers du répertoire. 2) Types primitifs de données, opérateurs, et instructions de contrôle Introduction Comme « tout » langage de programmation, Java est basé sur l’utilisation de types primitifs de données, d’opérateurs, et d’instructions de contrôle. Le tableau suivant résume ces différents éléments. Types primitifs Opérateurs Entier Flottant Texte Booléen Pas de type Arithmétiques Relationnels Logiques Affectation Cast (in,de)crémentation byte, short, int, long float, double char bool void +, -, *, /, % <, <=, >, >=, ==, != !, &, ^, |, &&, || = (type) ++, -- ?: new . if, else, elseif switch case do while for break, continue Ces diffèrents éléments sont similaires entre les langages de programmation, on les retrouve dans les langages C et C++ par exemple. Nous détaillons ici quelques points particuliers. Implémenter et commenter les exemples suivants, vous pouvez créer une nouvelle classe Test1 comme le montre l’exemple suivant. Dans cette classe, implémenter de nouvelles méthodes test() pour chacun de vos tests. Mettre en œuvre cette classe depuis votre classe principale App. class Test1 { void testa() {…} void testb() {…} } class App { public static void main(String args[]) { Test1 t = new Test1(); t.testa(); } } Types primitifs de données 1. Déclaration int a = 1; {int b=2;} int b=3; System.out.println(a+b); Opérateurs 2. L’opérateur modulo int a = 11%4; System.out.println(a); 2 3. Opérateurs d’affectation élargie int a=2,b=2; System.out.println(a = a+3); System.out.println(b += 3); 4. Priorités entre opérateurs int i=0; System.out.println((i++) == 0); int j=0; System.out.println((j+=1) == 0); 5. Opérateurs de court-circuit int i=0; if(false && (i++==0)){} System.out.println(i); int j=0; if(false & (j++==0)){} System.out.println(j); 6. Opérateur de Cast System.out.println(1.2/0.7); System.out.println((int)(1.2/0.7)); 7. Opérateur conditionnel int a=1,b=2,m1,m2; if(a>b) m1=a; else m1=b; System.out.println(m1); m2 = a>b ? a : b; System.out.println(m2); 8. Opérateur new System.out.println(new HelloWorld()); HelloWorld my1 = null; HelloWorld my2 = new HelloWorld(); System.out.println(my1+" "+my2); my2 = new HelloWorld(); System.out.println(my1+" "+my2); Remarque : L’opérateur delete n’existe pas en Java, en effet la désallocation des objets est assurée par le garbage collector « ramasse-miettes ». 9. Opérateur point HelloWorld my = new HelloWorld(); my.sayHello(); System.out.println(my.hello); La méthode sayHello() de l’objet my de type HelloWorld est appelé via l’opérateur point ., tel que my.sayHello(). Il en est de même pour la donnée membre hello. Instruction de contrôle 10. Conditions imbriquées int b; for(int a=0;a<10;a++) { if(a<5) b=1; else if((a>=5)&(a<8)) b=2; else if((a>=8)&(a<9)) b=3; else b=4; System.out.println(b); } 11. Instruction for (1) int i=0; for(i=0;i<5;i++) System.out.println(i); i=0; for(;i<5;i++) System.out.println(i); i=0; for(;(i+=1)<5;) System.out.println(i); 12. Instruction for (2) for(int i=0, j=10;j>i;i++,j--) System.out.println(i+";"+j); 3 int t1[], t2[] = {1,2,3}; t1 = t2; t1[0] = 4; System.out.println(t2[0]+";"+t1[0]); for(int i=0, j=10; ;i++,j--) { System.out.println(i+";"+j); if(j<i) break; } update(t2); System.out.println(t2[1]+";"+t1[1]); } 3) Tableaux Comme « tout » langage de programmation, Java permet la manipulation de tableaux. Cependant, Java fait preuve d’originalité sur ce point en considérant les tableaux comme des objets, et en permettant la composition de tableaux multi-dimensionnels à partir de tableaux de dimensions inférieures. Nous illustrons ici l’utilisation des tableaux en Java à travers quelques exemples. Implémenter et commenter les exemples suivants (vous pouvez créer une nouvelle classe Test2) : 1. Déclaration, allocation, initialisation, et accès int [] t1 = new int[3]; int t2[] = {1,2,3}; for(int i=0;i<3;i++) System.out.println(t1[i] + ";" + t2[i]); 2. Taille et affectation int [] t1 = new int[3]; int t2[] = {1,2,3}; for(int i=0;i<t1.length;i++) { t1[i] = t2[i]; System.out.println(t1[i] + ";" + t2[i]); } A travers cet exemple, vous pouvez voir l’utilisation des tableaux comme objets en Java. En effet, un objet tableau inclut une donnée membre length correspondant à la taille du tableau. On accède à cette donnée membre via l’utilisation de l’opérateur point ., t1.length. 3. Affectation et passage par argument void update(int t[]) { if(t.length>=2) t[1] = 5; } A travers cet exemple, vous pouvez voir que l’affectation de tableaux, ainsi que le passage de tableaux par argument à une fonction, se fait par adresse : en Java on parle de référence. Ces propriétés sont en fait communes à tous les objets en Java. Ces différentes notions seront abordées plus en détails dans les TP suivants. 4. Tableaux à plusieurs dimensions (1) int t1[][] = new int[2][3]; int [][]t2 = {{1,2,3},{4,5,6}}; for(int i=0;i<t1.length;i++) for(int j=0;j<t1[i].length;j++) { System.out.println(t1[i][j]); System.out.println(t2[i][j]); } 5. Tableaux à plusieurs dimensions (2) int t[][] = new int[2][]; int t1[] = {1,2,3}, t2[] = {4,5,6,7,8}; t[0] = t1;t[1] = t2; t1[1] = 0; t2[2] = 0; for(int i=0;i<t.length;i++) for(int j=0;j<t[i].length;j++) System.out.println(t[i][j]); 4) Chaînes de caractères Introduction Java permet la manipulation de chaînes de caractères. Ces chaînes de caractères sont en fait des objets, instance de la classe standard Java String. Leur utilisation est assez proche des tableaux. Java fait preuve d’originalité sur la gestion des chaînes de caractères, en imposant que les objets de type String ne soient pas modifiables. Ils restent cependant utilisables pour la création de nouveaux objets. void test() { 4 API specification Avant d’aborder plus en détails la classe String, il nécessaire d’utiliser l’API specification de la plate forme Java 2 SDK. Ouvrir avec votre explorateur le fichier C:\j2sdk1.4.1_02\docs\api\index.html, et placer ce fichier en raccourci sur votre système (vous aurez à l’utiliser de nombreuses fois). Cette documentation html correspond à la documentation de toutes les classes standards distribuées avec la plate forme Java 2 SDK. Ces classes sont regroupées par package. Le package correspond à un ensemble de classes (ou une librairie de classes spécifiques). La notion de package sera abordée plus en détails dans les TP suivants. Si vous faîtes défiler la barre de déroulement de la fenêtre bas gauche, vous avez un aperçu du nombre de classe à disposition. Ajoutez à ça le volume « important » de projet Java à disposition sur Internet, nous venons d’illustrer que la puissance du langage Java ne réside pas seulement dans le langage en lui même, mais aussi par sa popularité. Remarque : La documentation API specification est obtenu par utilisation de l’outil javadoc à partir du code source Java des packages standrards Java, en respectant les règles de commentaire présentées en introduction de ce TP. Javadoc sera abordée plus en détails dans les TP suivants. Manipulation Nous illustrons ici l’utilisation des chaînes de caractères en Java à travers quelques exemples. Implémenter et commenter les exemples suivants (vous pouvez créer une nouvelle classe Test3) : 1. Déclaration, allocation, et initialisation String s1 = new String("hello"); String s2 = "hello"; String s3 = new String(s1); System.out.println(s1 + " " + s2 + " " + s3); 2. Affectation String s1 = "hello1", s2 = s1; System.out.println(Integer.toHexString(s1.hashCode())); s1 = "hello2"; System.out.println(s1 + " " + s2); System.out.println(Integer.toHexString(s1.hashCode())); On admettra dans ce TP l’écriture de Integer.toHexString(o.hashCode()) pour la récupération sous forme de chaîne de caractères de la référence de l’objet o. Comparer cet exemple avec l’exemple (3) des tableaux, qu’en concluez vous ? 3. Opérateurs arithmétiques, d’affectation, et d’affectation élargie String s1 = "Java", s2 = "2"; String s = s1 + s2; System.out.println(s); s1 += s2; System.out.println(s1); 4. Opérateurs relationnels String s1 = "Java", s2 = System.out.println(s1 == System.out.println(s1 != System.out.println(s1 == 5. "Java"; s2); s2); s1); Longueur, accès aux caractères, recherche, et sous chaînes String s = "JavaTM 2 Platform"; char c; for(int i=0;i<s.length();i++) {c = s.charAt(i);System.out.println(c);} int b = s.indexOf('T'); int e = s.indexOf('a',b); String r = s.substring(b+1,e); System.out.println(r); 6. Comparaison, modification, et conversion String s1 = "Java"; String s2 = "Jovo"; System.out.println(s1.equals(s2)); s2 = s2.replace('o','a'); System.out.println(s1.equals(s2)); String cvt = new String(); for(int i=1;i<=2;i++) {System.out.println(s2+cvt.valueOf(i));} 4) Algorithmes de tri 5 Dans cette partie, on se propose de mettre en oeuvre les bases de programmation Java vues au cours de ce TP pour l’implémentation d’algorithmes de tri. On se propose de trier la chaîne de caractères « asortingexample » avec trois algorithmes de tri différents : par sélection, par bulle, et par insertion. Nous présentons ici ces trois algorithmes en langage naturel, ainsi que leurs résultats : pour i variant de début à fin -1 pour j variant de i+1 à fin si tableau (j) < tableau (i) permuter (i, min) fin si fin pour fin pour Sélection asortingexample asortingexample aasrtonigxemple aaestronixgmple aaeetsronximplg aaeegtsroxnmpli aaeegitsrxonpml aaeegiltsxropnm aaeegilmtxsrpon aaeegilmnxtsrpo aaeegilmnoxtsrp aaeegilmnopxtsr aaeegilmnoprxts aaeegilmnoprsxt aaeegilmnoprstx Sélection pour i variant de début à fin pour j variant de fin à i+1 si tableau (j) < tableau (j-1) permuter (j, j-1) fin si fin pour fin pour pour i variant de 3 à fin el tableau (i) ji tant que el < tableau(j-1) tableau (j) tableau (j-1) décrémenter j si j <0 fin tant que fin si fin tant que tableau(j) el fin pour Bulle asortingexample aasortingexempl aaesortingexlmp aaeesortinglxmp aaeegsortinlmxp aaeegisortlnmpx aaeegilsortmnpx aaeegilmsortnpx aaeegilmnsortpx aaeegilmnosprtx aaeegilmnopsrtx aaeegilmnoprstx aaeegilmnoprstx aaeegilmnoprstx aaeegilmnoprstx aaeegilmnoprstx 'n','g','e','x','a','m','p','l','e'}; void select(){} void bubble(){} void insert(){} void exchange(int i, int j) { char e; e = t[i]; t[i] = t[j]; t[j] = e;} void print() {System.out.println(new String(t));} } Que pouvez vous conclure sur la comparaison de ces trois algorithmes ? Insertion asortingexample asortingexample aasrtonigxemple aaestronixgmple aaeetsronximplg aaeegtsroxnmpli aaeegitsrxonpml aaeegiltsxropnm aaeegilmtxsrpon aaeegilmnxtsrpo aaeegilmnoxtsrp aaeegilmnopxtsr aaeegilmnoprxts aaeegilmnoprsxt aaeegilmnoprstx Bulle Insertion Pour ce faire, on se propose d’adopter une démarche objet respectant le squelette de classe suivant : class Sort { char t[]= {'a','s','o','r','t','i', 6