Tour d'horizon de certains éléments de syntaxe et du JDK. ## Hello World Une [[Glossaire général#Syntaxe|syntaxe]] assez proche similaire à celle de C ```java IO.println("Hello World"); ``` ### Hello World moderne `*` `Hello.java` ```java void main(){ IO.println("Hello World!"); } ``` - Point d'entrée : `main()` - Écrire du texte : `IO.println()` Exécuter du code ```shell java Hello.java Hello World! ``` `*` *Cette syntaxe simplifiée pour faciliter l'apprentissage est possible depuis les versions récentes 21-25 de Java ### JDK, JRE, version de Java JDK : Java Development Kit = outils pour développer en Java - -> Compiler le code - -> Exécuter le code (JRE) ![[java-cli-compile-and-execute-java-file.webp|360]] Vérifier la version de java ```shell java -version openjdk version "25.0.1" 2025-10-21 LTS OpenJDK Runtime Environment Temurin-25.0.1+8 (build 25.0.1+8-LTS) OpenJDK 64-Bit Server VM Temurin-25.0.1+8 (build 25.0.1+8-LTS, mixed mode, sharing) ``` Exécuter le code java (depuis java 25) ```shell java Hello.java Hello World! ``` ### En vrai, c'est un peu plus compliqué ![[compile-javac-bytecode-java-run.webp|600]] > [!note]- Dans la vraie vie on utilise peut `javac` directement > Compiler un java est simple quand il n'y a que quelques fichiers. > Quand un programme devient plus complexe, on s'appuie sur des outils de plus haut niveau pour packager nos programmes : > - IDE > - Gestionnaire de paquet comme Maven ou Gradle > ### Hello World de "boomer" ```java public class Main { public static void main(String[] args) { System.out.println("Hello World"); } } ``` **Point d'entrée d'un programme Java** Une **classe** contenant une **méthode** `public static void main(...)` Compiler le code ```shell javac Main.java ``` Exécuter le code ```shell java Main ``` > [!info] Classpath > > Si le code est présent dans un sous-dossier (souvent `src` ou `src/main/java`), il faut l'indiquer à la commande `java` avec l'argument `-classpath` > > ```sh > javac src/Main.java > ``` > > ```text > . > └── src > ├── Main.class > ├── Main.java > ``` > > ```sh > java -classpath src Main > ``` ## Mots-clés réservés de Java Plus de 50 [[Glossaire général#Mot‑clé|mots-clés]] sont réservés dans le langage Java. Pas besoin de tous les mémoriser pour le moment ! ```text abstract assert boolean break byte case catch char class const continue default do double else enum extends final finally float for goto if implements import instanceof int interface long native new package private protected public return short static strictfp super switch synchronized this throw throws transient try void volatile while true false null _ record sealed permits var yield module open opens requires transitive exports to uses provides with ``` > [!important] Vous ne pouvez pas nommer les variables comme bon vous semble, s'ils sont réservés par des mots-clés de java. ### Exo : Trouver le mot-clé ```java public class Main { public static void main(String[] args) { System.out.println("Hello World"); } } ``` Parmi - class - main - Main - println ### Exo : Remplir les trous ![[keywords-fill-gaps.webp|500]] - `class` - `System.out.println` - `public` > [!success]- réponse > ```java > public class HelloWorld { > String greeting = "Hello, World!"; > System.out.println(greeting); > } > ``` ## Variables ### Déclarer une variable En java, déclarer une [[Glossaire général#Variable|variable]] consiste à [[Glossaire général#Identifiant (ou nom)|nommer]] une valeur (ou le résultat d'une expression) et en expliciter le type. **Affecter** une valeur (scalaire) à une variable se fait avec l’opérateur d’affectation `=` ```java int entier = 15; ``` - `int` : type de la variable (ici un entier) - `entier`: nom de la variable (ne doit pas être un [[Java - Essentiels#Mots-clés réservés de Java|mot-clé réservé]]) - `15`: valeur de la variable Affecter la **valeur d'une expression** à une variable ```java int somme = 2 + 3; ``` Pour approfondir : https://dev.java/learn/language-basics/variables/ ### Opérateurs d'affectation combinés - `+=` : Addition et affectation - `-=` : Soustraction et affectation - `*=` : Multiplication et affectation /= : Division et affectation - `%=` : Modulo et affectation - ... ```java int a = 10; a += 5; // a = a + 5 System.out.println(a); // Affiche 15 ``` Pour approfondir : - https://dev.java/learn/language-basics/using-operators/ - https://dev.java/learn/language-basics/all-operators/ ### Variables `final` ```java final int somme = 2 + 3; // Erreur de compilation somme = 5; ``` > [!info] Evolution du langage vers le [[Immuabilité et non-modifiable|non-modifiable et l'immuabilité]] > Le langage Java propose de plus en plus de mécanismes et constructions du langage tendant à empecher de modifier ou de muter des données. > Cela a des avantages lorsqu'on fait de la [[Glossaire général#Programmation concurrente|programmation concurrente]]. > > Ex. > - Types immuable : `String`, `BigDecimal`, `BigInteger`, types de l'API `java.time` > - Collections non modifiables : `List.of(...)`, `Set.of(...)`, `Map.of(...)`, `Collections.unmodifiableXxxx(...) > - Types énumérés > - Records > ### Portée d'une variable Voir [[Encapsulation en Java#Portée lexicale (blocs)]] ### `var` (Inférence de type) Si le type d'une variable n'est pas ambigü, il peut être **inferré**. ```java var texte = ""; // Type inferé : String ``` ## Structures de contrôle Les classiques de C se retrouvent en Java : conditions, boucles, switch/case... ```java if (condition){ // ... } else if(autre condition){ // ... } else { // ... } ``` ```java while (condition) { // ... } ``` ```java for (int i = 0; 1 <10 ; i++){ // ... } ``` ```java switch (foo) { case "bar":{ System.out.println("Bar"); break; } case "baz":{ System.out.println("Baz"); break; } default: System.out.println("Default"); break; } ``` Pour approfondir : https://dev.java/learn/language-basics/controlling-flow/ ## Types de données en Java ### Types primitifs - **byte** : nombres entiers entre -128 et 127 - **short** : nombres entiers entre -32 768 et 32 767 - **int** : nombres entiers signés sur 32 bits - **long** : nombres entiers signés sur 64 bits - **float** : nombres décimaux en arithmétique à virgule flottante ([IEEE 754](https://fr.wikipedia.org/wiki/IEEE_754)) a précision de 32 bits. Suffisant pour 6 à 7 chiffres après la virgule - > [!warning]- Ne pas utiliser pour des calculs précis, utiliser `java.lang.BigDecimal` (ex. calculs sur la monnaie) (idem pour double) - **double** : nombres décimaux en arithmétique à virgule flottante ([IEEE 754](https://fr.wikipedia.org/wiki/IEEE_754)) a précision de 64 bits. Suffisant pour 15 à 16 chiffres après la virgule - > [!warning]- Ne pas utiliser pour des calculs précis, utiliser `java.lang.BigDecimal` (ex. calculs sur la monnaie) (idem pour double) - **boolean** : true ou false - **char** : caractère unicode sur 16 bits https://dev.java/learn/language-basics/primitive-types/ https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html ### Types primitifs et valeurs par défaut Les types primitifs peuvent être initialisés à vide. Ils prennent une valeur par défaut dans ce cas. ```java short s; // 0 int i; // 0 long l; // 0 float f; // 0.0 double d; // 0.0 byte by; // 0 boolean bo; // false char c; // \u0000' ``` --- ### Types non primitifs (références) Les types non primitifs sont des types de données qui sont inclus dans le langages mais qui sont représentées par des classes. Chaque variable est une référence vers un objet. Ils disposent de méthodes utilitaires additionnelles - `String` - Types primitifs "boxés" : `Integer` , `Long`, ... - Tableaux - classes - objets ```java int[] entiers= new int[]{1,2}; entiers.length; // 2 String text = "Coda"; text.length(); text.toLowerCase(); ``` --- ## The billion dollar mistake : `null` references Les types référence peuvent ne pointer vers aucune valeur. Dans ce cas, leur valeur est `null`. Lorsqu'on tente de déréférencer une variable dont le type est `null`, on se prend la fameuse `NullPointerException`. ```java String mario = null; marion.toUpperCase(); // NullPointerException ``` Java ne dispose pas encore de mécanique native pour éviter les valeurs `null` par défaut (contrairement à Kotlin par exemple). https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/ > [!note] Les types primitifs ne peuvent pas avoir de valeur `null` ## Parenthèse sur la pile et le tas La [[Glossaire général#Pile (zone de mémoire)|pile]] (stack) est l'espace mémoire contenant les valeurs primitives et permettant au programme de savoir où il en est de l'exécution de celui-ci. Le [[Glossaire général#Tas (zone de mémoire)|tas]] (heap) est l'espace mémoire utilisé pour les **allocations dynamiques** , en gros pour les valeurs des variables. > [!exemple]- Code java > ```Java > class Person { > int id; > String name; > > public Person(int id, String name) { > this.id = id; > this.name = name; > } > } > > public class PersonBuilder { > private static Person buildPerson(int id, String name) { > return new Person(id, name); > } > > public static void main(String[] args) { > int id = 23; > String name = "John"; > Person person = null; > person = buildPerson(id, name); > } > } > ``` > > ![[java-heap-stack.png|520x293]] > Source : https://www.baeldung.com/java-stack-heap > [!tip]- Stack en musique > [!!Con 2019- Tail Call Optimization: The Musical!! by Anjana Vakil & Natalia Margolis ](https://www.youtube.com/watch?v=-PX0BV9hGZY&t=125s) ## Muabilité et immuabilité [[Immuabilité et non-modifiable]] En java, par défaut les types référence sont muables. ## `String` En Java les chaînes de caractères sont des instances de la classe `String` Chaines de caractères et concaténation ```java String greeting = "Hello"; String text = greeting + "World"; String multilineText = "line 1\n line 2; String text2 = "Hello " + 4; ``` https://dev.java/learn/numbers-strings/ ### Echappement des caractères spéciaux Comment inclure le caractère quote puisqu'il indique un début de données et une fin de données? ```java String text = "Bonjour je m'appelle \"Marc\""; System.out.println(text); ``` ```text Bonjour je m'appelle "Marc" ``` ### Conversion explicite ```java String a = "10"; int b = Integer.parseInt(a); // Conversion explicite en entier System.out.println(b); // Affiche 10 String a = "10.5"; double b = Integer.valueOf(a); // Conversion explicite en chiffre à virgule System.out.println(b); // Affiche 10.5 ``` > [!tip] Cast (Transtypage) > Vous pouvez forcer une conversion (transtypage) avec en précédant une expression par `(type)` si les types sont compatibles. Si ce n'est pas le cas, vous obtiendrez une erreur de compilation, ou pire une exception à l'exécution `ClassCastException`. > > ```java > String foo = (String) 10; > ``` > > Notez que avoir recours à un transtypage est assez souvent le signe d'une erreur de conception. On ne devrait avoir à transtyper que très rarement. ## Afficher et lire du texte ### À l'ancienne Afficher du texte ```java System.out.print() System.out.println() ``` Lire du texte ```java Scanner sc = new Scanner(System.in); int a = sc.nextInt() double b = sc.nextDouble(); boolean c = sc.nextBoolean(); sc.close(); ``` ### Depuis Java 25 **Afficher du texte** ```java IO.println() IO.print() ``` Lire du texte ```java IO.readln() ``` ## Tableaux Les tableaux permettent de stocker un **nombre fixe** de données Ils sont indexés à partir de 0. ![[dev-java-array-structure.png]] Source : https://dev.java/learn/language-basics/arrays/ ```java String[] strings = new String[]{"Foo", "Bar",}; // Syntaxe compacte String[] otherStrings = {"Foo", "Bar",}; String foo = strings[0]; // "Foo" strings[1] = "bar"; strings[10] = "bar"; // ArrayIndexOutOfBoundsException int[] array = new int[10]; int[] numbers = { 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; String[] texts; // null ``` ### A plusieurs dimensions ```java int[][] array2D = new int[][]{ {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}, {16, 17, 18, 19, 20}, {21, 22, 23, 24, 25}, }; int number = array2D[2][3]; // 14 ``` ### Parcourir un tableau Avec une boucle classique ```java int[] numbers = {10, 20, 30, 40, 50}; for (int i = 0; i < numbers.length; i++) { System.out.println("Indice " + i + " : " + numbers[i]); } ``` Avec une boucle améliorée ```java for (int number : numbers) { System.out.println("Nombre : " + number); } ``` ### Arrays ```java import java.util.Arrays; ``` ```java int[] numbers = new int[5]; Arrays.fill(numbers, 42); Arrays.compare(array2D[0],array2D[1]); // false Arrays.deepEquals(array2D,new int[][]{{1,2,3}}); // false Arrays... ``` - Arrays.toString - Arrays.sort - Arrays.equals - Arrays.compareTo ... https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Arrays.html ## Collections Pour aller au delà des tableaux, Java propose des collections implémentant la plupart des algorithmes classiques de structures de données. Ces outils permettent de stocker, parcourir, et manipuler des ensembles d'objets. C'est présenté dans l'API Java par une hiérarchie de types. ![[dev-java-collection-hierarchy.png|320x292]] Source : https://dev.java/learn/api/collections-framework/organization/ Les collections contrairement aux tableaux ont des tailles dynamiques Elles font partie du package Java.util et il faut les inclure au début du programme. ### List - ArrayList Une ArrayList permet de stocker une liste d’objets (dont des valeurs `null`. Elle possède de nombreuses méthodes permettant l'accès et la modification **indexée** (position de l'objet dans la liste). Contrairement aux tableaux, sa taille est variable. ```java import java.util.ArrayList; ``` ```java List<String> chasseurs = new ArrayList<String>() ; chasseurs.add("Bébert"); chasseurs.add("Robert"); chasseurs.add("Gérard"); System.out.println(chasseurs); // [Bébert, Robert, Gérard] // Ajout en position 3 chasseurs.add(2,"Dédé"); System.out.println(chasseurs); // [Bébert, Robert, Dédé, Gérard] // Remplacement en position 3 chasseurs.set(2,"André"); System.out.println(chasseurs); // [Bébert, Robert, André, Gérard] ``` Autres façons de déclarer une `ArrayList` dans une variable ```java Collection<String> names = new ArrayList<>() ; List<String> names = new ArrayList<>() ; var names = new ArrayList<String>() ; // Non recommandé, utiliser plutôt un type plus faible ArrayList<String> names = new ArrayList<String>() ; ``` https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/ArrayList.html Liste non modifiable ```java List<String> chasseurs = List.of("Bébert", "Robert", "Gérard"); ``` ### Set - HashSet Un Set est une collection dont chaque élément est unique. HashSet est une implémentation de Set qui détermine l'unicité de ses éléments par sa valeur (et par le résultat de la méthode `hashcode()` de l'objet contenu. ```java Set<String> chasseurs = new HashSet<>() ; chasseurs.add("Bébert"); chasseurs.add("Robert"); chasseurs.add("Gérard"); chasseurs.add("Gérard"); chasseurs.add("Gérard"); chasseurs.add("Gérard"); System.out.println(chasseurs); // [Gérard, Robert, Bébert] // Pas d'ordre particulier ``` ```java Set<String> chasseurs = new LinkedHashSet<>() ; chasseurs.add("Bébert"); chasseurs.add("Robert"); chasseurs.add("Gérard"); chasseurs.add("Gérard"); System.out.println(chasseurs); // [Bébert, Robert, Gérard] // Dans l'ordre d'apparition ``` `TreeSet` est un set basé sur une structure d'arbre qui trie des éléments comparables dans l'ordre naturel (déterminé par leur méthode `compareTo()`) ```java Set<String> chasseurs = new TreeSet<>() ; chasseurs.add("Bébert"); chasseurs.add("Robert"); chasseurs.add("Gérard"); chasseurs.add("Gérard"); System.out.println(chasseurs); // [Bébert, Gérard, Robert] // Dans l'ordre naturel (ici alphabétique) ``` Set non modifiable ```java Set<String> chasseurs = Set.of("Bébert", "Robert", "Gérard"); ``` ### Map - HashMap Une Map est un **dictionnaire** clé-valeur. `HashMap` en est un implémentation. HashMap (modifiable) ```java Map<Integer,String> nombresRomains = new HashMap<>(); nombresRomains.put(1,"I"); nombresRomains.put(2,"II"); nombresRomains.put(3,"III"); nombresRomains.put(4,"IV"); nombresRomains.put(5,"V"); nombresRomains.get(2); // "II" nombresRomains.remove(3); nombresRomains.size(); ``` Map non modifiable ```java Map<Integer,String> nombresRomains = Map.of( 1,"I", 2,"II", 3,"III", 4,"IV", 5,"V"); ``` ### Parcourir une collection : boucle foreach ```java Map<Integer,String> nombresRomains = Map.of( 1,"I", 2,"II", 3,"III", 4,"IV", 5,"V"); for (Integer nombreArabe : nombresRomains.keySet()){ System.out.println(nombreArabe+" : "+nombresRomains.get(nombreArabe)); } // 1 : I // 2 : II // 3 : III // 4 : IV // 5 : V for (String nombreRomain : nombresRomains.values()){ System.out.println(nombreRomain); } // I // II // III // IV // V Collection<String> chasseurs = new HashSet<>() ; chasseurs.add("Bébert"); chasseurs.add("Robert"); chasseurs.add("Gérard"); for (String chasseur : chasseurs){ System.out.println(chasseur); } // Bébert // Robert // Gérard Collection<String> chasseurs = new ArrayList<>() ; chasseurs.add("Bébert"); chasseurs.add("Robert"); chasseurs.add("Gérard"); for (String chasseur : chasseurs){ System.out.println(chasseur); } // Bébert // Robert // Gérard ``` ## Collections Utilitaires pour les collections ```java List<String> list = new ArrayList<>(List.of("Bébert","Dédé","Gérard")); Collections.shuffle(list); Collections.sort(list); Collections.max(list); // ... ``` ## Bibliothèques `import nom.de.package.NomDeClasse;` ```java import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; ``` ## Récap Nous avons examiné le programme le plus simple que vous pouvez écrire en Java. Il contient une seule classe avec une seule **main** méthode. Tout programme Java doit avoir une main méthode car c'est la première exécutée lors du lancement du programme. # À suivre [[JShell]]