Tutorat en bio-informatique 29 janvier 2013 Au programme… • Introduction au Java Java vs JavaScript • Fortement typé • Faiblement typé • Typage statique • Typage dynamique • Compilé • Interprété Éditeurs de texte • C’est ce qu’on utilise pour écrire un programme • Bloc-notes sur Windows en est un exemple (mais il y a beaucoup mieux!) • Sur Linux, plusieurs éditeurs de texte sont disponibles : Emacs, Vi, KWrite, gedit, etc. • Eclipse (environnement de développement) KWrite Emacs Console • La console sert à donner des commandes à l’ordinateur • On peut lancer des programmes (Emacs, KWrite) dans la console • On se sert également de la console pour lancer nos programmes Java Console Console Soit le programme 'Prog.java' • Compilation du programme : javac Prog.java • Exécution du programme : java Prog Types de variables • L’ordinateur garde en mémoire différents types de valeurs de différentes façons • Il faut indiquer à l’ordinateur quel type de variable sera utilisé • Vous ne seriez pas capables d’écrire un texte avec une calculatrice • De la même façon, un ordinateur ne pourra pas sauvegarder un texte dans un nombre entier Types de variables • Les types de variables les plus souvent utilisés : – int : nombre entier (2, -55, 1665442) – double : nombre décimal (-123.456, 7.5) – String : chaîne de caractères ("J’aime le jambon!") – char : 1 caractère (‘a’, ‘.’, ‘/’, ‘^’) Types de variables • Pour chaque type, on a : – Un ensemble d’opérations permises – Un nombre limité de valeurs possibles Types de variables • On choisit les types de nos variables en fonction de l’utilisation (et de la gestion de la mémoire) : – byte : -128 à 127 1 octet – int : -2 147 483 648 à 2 147 483 647 4 octets – double : ≈4.94e-324 à ≈ 1.79e308 8 octets (notez qu’il existe d’autres types que ceux-ci) Déclaration d’une variable • C’est le fait de créer une nouvelle variable en indiquant à l’ordinateur son type • En Java : int nombreEntier; double nombreDecimal; String phraseImportante; char caractere; Types de variables • Overflow : int nb1 = 2147483647; int nb2 = 1; int res = nb1 + nb2; // donne -2147483648 !!! On doit s’assurer que tous les résultats possibles d’une opération sont contenus dans les valeurs possibles du type. Types de variables • Vous ne pouvez pas sauvegarder des fonctions dans des variables en Java! Initialisation • Il est important d’initialiser (de donner une valeur initiale) les variables, sinon le traitement est impossible et cela provoque des erreurs à la compilation. Initialisation • Nombre entier : int nb = 575; • Caractère : char monA = ‘A’; • Chaîne de caractères : String maString = "mot"; Opérations arithmétiques • • • • • + * / % addition soustraction multiplication division modulo a+4 a–4 a*4 a/4 a%4 La division de 2 entiers (int) est une division entière le résultat est arrondi à l'entier inférieur : 9 / 10 = 0 Opérations • Division de 2 int int 5/2=2 • Addition de byte + int = int • Le résultat sera du même type que le type le plus précis de l'opération : nombres entiers nombres décimaux byte short int long float (évite la perte d’information) double Opérations • Addition de byte + int = int byte nb1 = 25; int nb2 = 300; byte result = nb1 + nb2; //erreur! int result2 = nb1 + nb2; //fonctionne Types • boolean : true ou false boolean b = true; if(b) System.out.println("Vrai!"); Casting • On peut avoir besoin de changer le type d’une variable. • Un exemple de mauvaise programmation! AGCTAAGTACAAAGTAACAG int nbA = 10; int nbNucleo = 20; double pourcentA = nbA / nbNucleo * 100; Ici, pourcentA sera égal à 0.0% !!! Casting • Un exemple en programmation (version 1.3): AGCTAAGTACAAAGTAACAG int nbA = 10; int nbNucleo = 20; double pourcentA = (double)nbA / nbNucleo * 100; Casting • Attention : une erreur de casting peut entraîner une perte d'information int x = 2; double y = 1.8; int result = (int) (y / x + 0.1); // result = 1 int x = 2; double y = 1.8; int result = (int) ((int) (y / x) + 0.1); // result = 0 int x = 2; double y = 1.8; int result = (int) ((int)y / x + 0.1); // result = 0 int x = 2; double y = 1.8; int result = (int)y / x + (int)0.1; // result = 0 Opérations sur les Strings • On peut utiliser un opérateur arithmétique (+) sur les Strings en Java (concaténation) : String s = "J’aime "; String s2 = "la programmation!"; String s3 = s + s2; //s3 devient: “J’aime la programmation!” • Pour écrire la chaîne de caractères s3 dans la console: System.out.println(s3); String int • Pour changer un String en int (après une entrée clavier par exemple): – int nbClavier = Integer.parseInt(stringClavier); • Pour changer un int en String (pour écrire dans la console par exemple) – String sortie = "" + 55; Constantes • On doit ajouter le mot réservé « final » avant le type. • On écrit le nom de la constante en lettres majuscules et on sépare les mots par des ‘_’ (convention). • Une seule affectation est permise. La deuxième provoquera une erreur à la compilation. • Exemple : final int MINUTES_DANS_HEURE = 60; Opérateurs de comparaison • Exemple : char a = 97; char b = 98; char D = 'D'; boolean bool1 = a < b; boolean bool2 = a < D; //true //false! Comparaison de String • Les opérateurs de comparaison ne sont pas définis pour les String. • On doit utiliser des méthodes (fournies) pour comparer deux String ou pour vérifier si deux String sont identiques. Comparaison de String • Méthode equals() retourne un boolean String s = "test"; if (s.equals("test")) System.out.println("Les String sont identiques"); • Méthode compareTo() retourne un int négatif (plus petit), 0 (identique) ou positif (plus grand) String s1 = "test2"; String s2 = "test3"; int compare = s1.compareTo(s2); //compare = -1 Comparaison de String • Comme pour les comparaisons de char, la méthode compareTo() compare les codes ASCII : String s1 = "test2"; String s2 = "Test2"; int compare = s1.compareTo(s2); //compare = 32 Comparaison de String • Méthode equalsIgnoreCase() – Même fonctionnement que equals(), mais ne fait pas la distinction entre les lettres majuscules et minuscules. • Méthode compareToIgnoreCase() – Même fonctionnement que compareTo(), mais ne fait pas la distinction entre les lettres majuscules et minuscules. Comparaison de double ou float • Pour comparer des double ou des float, il est préférable de vérifier la différence entre les deux nombres plutôt que de vérifier directement l'égalité : double a = 0.1 + 0.1 + 0.1; if (Math.abs(a - 0.3) < 0.001) { System.out.println("0.1 + 0.1 + 0.1 est égal à 0.3"); } a = 0.30000000000000004 !!! Switch char note = 'B'; switch (note) { case 'A': System.out.println("Excellent"); break; case 'B': System.out.println("Bon"); break; case 'C': System.out.println("Moyen"); break; default: System.out.println ("Note invalide"); } Switch • On peut utiliser les switch avec les types primitifs suivants : – – – – – byte short char int String (nouveau dans Java SE 7) Messages d’erreurs – erreurs syntaxiques public class MonProgramme { public static void main (String[] args) { int test = 0 } } MonProgramme.java:5: ';' expected int test = 0 ^ 1 error Messages d’erreurs – erreurs syntaxiques public class MonProgramme { public static void main (String[] args) { int test = 5.6; } } MonProgramme.java:5: possible loss of precision found : double required: int int test = 5.6; ^ 1 error Messages d’erreurs – erreurs syntaxiques public class MonProgramme { public static void main (String[] args) { String s = Allo; } } MonProgramme.java:5: cannot find symbol symbol : variable Allo location: class MonProgramme String s = Allo; ^ 1 error Messages d’erreurs – erreurs syntaxiques public class MonProgramme { public static void main (String[] args) { System.out.println("Blablabla."; } } MonProgramme.java:5: ')' expected System.out.println("Blablabla."; ^ 1 error Messages d’erreurs – erreurs syntaxiques public class MonProgramme { public static void main (String[] args) { String s; System.out.println(s); } } MonProgramme.java:6: variable s might not have been initialized System.out.println(s); ^ 1 error Messages d’erreurs – erreurs syntaxiques public class MonProgramme { public static void main (String[] args) { int age = 25; if (age < 18) { boolean adulte = false; } else { boolean adulte = true; } MonProgramme.java:15: cannot find symbol symbol : variable adulte location: class MonProgramme if (adulte) ^ 1 error if (adulte) { System.out.println(“Vous êtes un adulte”); } } } Messages d’erreurs – erreurs d'exécution public class MonProgramme { public static void main (String[] args) { String s = "Pizza"; String sub = s.substring(0, 15); } } Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 15 at java.lang.String.substring(String.java:1935) at MonProgramme.main(MonProgramme.java:6) Messages d’erreurs – erreurs d'exécution public class MonProgramme { public static void main (String[] args) { String s = "pizza"; System.out.println("J'aime la " + s); s = null; int longueur = s.length(); } } J'aime la pizza Exception in thread "main" java.lang.NullPointerException at MonProgramme.main(MonProgramme.java:8) Messages d’erreurs – erreurs d'exécution public class CalculTaxes { public static void main (String[] args) { //L'utilisateur doit donner en argument un prix et les taxes seront calculees double prix = Double.parseDouble(args[0]); double avecTaxes = prix * 1.05 * 1.085; System.out.println("Le prix du produit avec les taxes est égal à : " + avecTaxes); } } java CalculTaxes Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at CalculTaxes.main(CalculTaxes.java:6) Messages d’erreurs – erreurs d'exécution public class CalculTaxes { public static void main (String[] args) { //L'utilisateur doit donner en argument un prix et les taxes seront calculees double prix = Double.parseDouble(args[0]); double avecTaxes = prix * 1.05 * 1.085; System.out.println("Le prix du produit avec les taxes est égal à : " + avecTaxes); } } java CalculTaxes abc Exception in thread "main" java.lang.NumberFormatException: For input string: "abc" at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224) at java.lang.Double.parseDouble(Double.java:510) at CalculTaxes.main(CalculTaxes.java:6) Un exemple de prévention d'erreurs d'exécution public class CalculTaxes { public static void main (String[] args) { //L'utilisateur doit donner en argument un prix et les taxes seront calculees if (args.length != 1) { System.out.println("Vous devez donner un argument!"); System.exit(0); //On quitte le programme si il n'y a pas un seul argument } try//On essaie... { double prix = Double.parseDouble(args[0]); double avecTaxes = prix * 1.05 * 1.085; System.out.println("Le prix du produit avec les taxes est égal à : " + avecTaxes); } catch(Exception e) //... et on quitte le programme s'il se produit une erreur { System.out.println("L'argument doit être un nombre!"); System.exit(0); } } Les boucles for for (int i = 0; i < 5; i++) Initialisation d'un compteur (une variable) La condition Les deux ';' servent à séparer les trois éléments qui sont à l'intérieur des parenthèses. De quelle façon la valeur du compteur doit changer à la fin de l'itération Les boucles while while (i < 5) La condition • Dans ce cas, la variable 'i' doit être déjà déclarée (et initialisée). • On peut évidemment utiliser un boolean comme condition. Les boucles do-while do { instructions } while (i < 5); La condition • Dans ce cas, la variable 'i' doit être déjà déclarée. • On peut évidemment utiliser un boolean comme condition. Les fonctions • Une grande quantité de fonctions sont déjà offertes par Java dans ses différentes classes. • Vous les avez probablement déjà utilisées : – Dans la classe String : • • • • maString.length(); maString.substring(0, 10); maString.equals(string); maString.compareTo(string); – Dans la classe System : • System.exit(0); – Dans la classe PrintStream : • System.out.println(string); – Dans la classe Math : • Math.abs(-5); Les fonctions • Vous avez même déjà créé une fonction : public class MonProgramme { public static void main (String[] args) { System.out.println("Quelque chose…"); } } La fonction main est une fonction qui est appelée automatiquement au lancement du programme, plus précisément au lancement de la classe qu'on exécute. Les fonctions • Les fonctions doivent être définies à l'intérieur de la classe, mais à l'extérieur de la fonction main (si elle existe). public class MonProgramme { public static void main (String[] args) { System.out.println("Quelque chose…"); } Définir les fonctions ici! } Les fonctions • Il est interdit de définir des fonctions à l'intérieur d'une autre fonction en Java! Les fonctions • La définition d'une fonction comprend la signature et le bloc d'instructions. public static <valeur de retour> nomDeFonction(<type> paramètre, …) { … } • Par convention, on choisit un verbe comme nom de fonction. Les fonctions • Les fonctions avec valeur de retour et sans paramètre : On peut définir une fonction "trouveTaxes" pour calculer le taux correspondant aux deux taxes. //Fonction qui retourne le taux des deux taxes public static double trouveTaxes() { double taux = 1.05 * 1.085; return taux; } Si vous oubliez l'instruction return, vous allez avoir ce message d'erreur à la compilation: missing return statement. Les fonctions • Les fonctions sans valeur de retour et avec un ou plusieurs paramètres : On peut améliorer la fonction "quitter" en lui faisant imprimer un message d'erreur spécifique à la situation: //Pour imprimer un message d'erreur donné en paramètre et quitter le programme public static void quitter (String message) { System.err.println(message); System.exit(0); } Les fonctions • Avec les fonctions, il faut bien comprendre la notion de portée des variables, c'est-à-dire à quels endroits les variables sont accessibles. • Les fonctions n'ont pas accès aux variables que vous utilisez dans une autre fonction (y compris la fonction main). • Les fonctions ont seulement accès à ce qui a été passé en paramètre (et aux variables static de classe). Les fonctions • Contrairement aux variables, plusieurs fonctions peuvent avoir exactement le même nom, en autant que les paramètres soient différents. public static void dessine() //public static String dessine() //pas permis par le compilateur! public static void dessine(int x, int y) public static void dessine(int x) public static void dessine(double x, double y) • Les 4 fonctions en noir sont différentes et il n'y aurait aucune erreur lors de la compilation. Les variables static de classe • Les variables static de classe sont accessibles partout dans la classe, donc dans toutes les fonctions. • Vous pouvez vous en servir pour déclarer des constantes et elles seront accessibles partout dans votre programme. public class MonProgramme { public static final int MINUTES_DANS_HEURE = 60; public static void main (String[] args) { System.out.println("Minutes dans une heure = " + MINUTES_DANS_HEURE); } } Tableaux • Lorsqu'on initialise un tableau, on a deux choix : – On donne la taille du tableau (le nombre de cases) – On donne la liste complète des éléments du tableau • Au minimum, on doit donc connaître la taille du tableau (si on ne connaît pas encore la liste des éléments à insérer). • La taille choisie est définitive. Il sera impossible de la modifier plus tard. Tableaux • Initialisation avec taille seulement : int[] tabInt = new int[10]; String[] tabString = new String[25]; • Initialisation avec tous les éléments : double[] tabDouble = {1.2, 2.22, 5.44, 6.1}; String[] tabString2 = {"test", "test2", "test3"}; Tableaux • Pour accéder à une case du tableau, autant pour lire la valeur de la case que pour la modifier : int[] tabInt = new int[2]; tabInt[0] = 555; tabInt[1] = 23; int test = tabInt[0]; tabInt[1] = tabInt[0]; • Il faut faire attention à ne pas accéder à une position (case) qui n'existe pas. Tableaux • Pour obtenir la taille d'un tableau : int[] tabInt = {0,1,2,3,4,5}; int size = tabInt.length; • Attention : – La taille du tableau correspond au nombre total de cases, mais les positions des cases commencent à partir de 0. Tableaux • Lorsqu'on initialise un tableau avec la taille, les cases ne sont pas initialisées. • Les cases contiendront la valeur par défaut du type primitif, ou null pour les objets et les String. • Valeurs par défaut : – int : 0 – double : 0.0 – boolean : false Tableaux String[] tabString = new String[10]; tabString null null null null null null null null null null Tableaux String[] tabString = new String[10]; tabString[0] = "test"; tabString "test" null null null null null null null null null Tableaux String[] tabString = new String[10]; tabString[0] = "test"; tabString[1] = tabString[0]; tabString "test" "test" null null null null null null null null Tableaux String[] tabString = new String[10]; tabString[0] = "test"; tabString[1] = tabString[0]; tabString[2] = tabString[1] + "2"; tabString "test" "test" "test2" null null null null null null null Tableaux String[] tabString = new String[10]; tabString[0] = "test"; tabString[1] = tabString[0]; tabString[2] = tabString[1] + "2"; tabString[9] = "fin"; tabString "test" "test" "test2" null null null null null null "fin" Tableaux String[] tabString = new String[10]; tabString[0] = "test"; tabString[1] = tabString[0]; tabString[2] = tabString[1] + "2"; tabString[9] = "fin"; tabString[10] = "fin2"; Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10 tabString "test" "test" "test2" null null null null null null "fin" Tableaux 2D • On peut utiliser des tableaux à 2 dimensions : int[][] tab2d = new int[5][5]; tab2d[0][0] = 5; tab2d[2][3] = 7; 5 0 0 0 0 tab2d 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0