Tour d'horizon de certains éléments de syntaxe et du JDK. ## Hello World Une [[Glossaire - Programmation#Syntaxe|syntaxe]] assez proche similaire à celle de C ```java IO.println("Hello World"); ``` ### Hello World depuis Java 25 > [!warning] Depuis java 21-25 > Cette **syntaxe simplifiée** pour faciliter l'apprentissage est possible depuis les **versions récentes 21-25** de Java `Hello.java` ```java void main(){ IO.println("Hello World!"); } ``` - Point d'entrée : `main()` - Écrire du texte : `IO.println()` Exécuter du code depuis un terminal ```shell java Hello.java Hello World! ``` ### JDK, JRE, version de Java [[Glossaire - Programmation#JDK|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]] ### Exécuter le code java `java NomDeFichier.java` ```shell java Hello.java Hello World! ``` ### Vérifier la version de java `java -version` ```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) ``` ### En vrai, c'est un peu plus compliqué En général, on ne se contente pas d'exécuter qu'un seul fichier .java. On veut [[Glossaire - Programmation#Compilation|compiler]] un ensemble de fichiers java. `javac NomDeMonFichier.java` Un fichier `NomDeMonFichier.class` est créé. Il contient le [[Glossaire - Programmation#Bytecode|bytecode]] qui pourra être [[Glossaire - Programmation#Langage interprété|interprété]] par la [[Glossaire - Programmation#JVM|JVM]] ![[compile-javac-bytecode-java-run.webp|600]] > [!tip] Dans la vraie vie on utilise rarement `javac` > > 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 : > - [[Glossaire - Programmation#IDE|IDE]] > - [[Glossaire - Programmation#Gestionnaire de dépendances|Gestionnaire de paquet]] comme [[Glossaire - Programmation#Maven|Maven]] ou [[Glossaire - Programmation#Gradle|Gradle]] <div style="page-break-after: always;"></div> ### Hello World "classique" Dans des versions de Java **plus anciennes que 21-25**, on est obligé d'écrire le programme principal de la façon suivante : > [!success] Ce code fonctionne pour toutes les versions de Java `Main.java` ```java public class Main { public static void main(String[] args) { System.out.println("Hello World"); } } ``` **Point d'entrée d'un programme Java** Une **[[Glossaire - Programmation#Classe|classe]]** contenant une **[[Glossaire - Programmation#Méthode statique|méthode]]** `public static void main(...)` Compiler le code ```shell javac Main.java ``` Exécuter le code ```shell java Main ``` ### Classpath Le [[Glossaire - Programmation#Classpath|classpath]] est un ou plusieurs dossiers ou la commande java s'attend à trouver des fichiers .java, des classes, des ressources ou des bibliothèques externes. On doit le définir quand on exécute la commande `java`. Ex. 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` Compilation d'un fichier java ```sh javac src/Main.java ``` Le fichier .class correspondant se retrouve dans le dossier `src` ```text . └── src ├── Main.class ├── Main.java ``` On doit spécifier que `src` fait partie du classpath pour que la commande java trouve le code : ```sh java -classpath src Main ``` ## Mots-clés réservés de Java Plus de 50 [[Glossaire - Programmation#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] Les mots-clés sont réservés > Vous ne pouvez pas nommer les variables ou méthodes 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|400x162]] - `class` - `System.out.println` - `public` > [!success]- réponse > ```java > public class HelloWorld { > String greeting = "Hello, World!"; > System.out.println(greeting); > } > ``` <div style="page-break-after: always;"></div> ## Variables ### Déclarer une variable En java, déclarer une [[Glossaire - Programmation#Variable|variable]] consiste à [[Glossaire - Programmation#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 [[2.1 - 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` Les variable précédées par le mot-clé `final`ne peuvent pas être affectées plus d'une fois. ```java final int nombre = 1; // Erreur de compilation nombre = 2; ``` <div style="page-break-after: always;"></div> ### Portée d'une variable locale Une [[Glossaire - Programmation#Variable locale|variable locale]] est déclarée à l'intérieur d'une méthode ou d'un **bloc** à l'intérieur de cette méthode. Une variable locale n'est accessible que : - **après** qu'elle ait été définie - depuis **le bloc de la méthode** où elle est définie - depuis **un sous-bloc** C'est ce qu'on appelle la [[Glossaire - Programmation#Portée lexicale|portée lexicale]] On verra plus tard avec les [[Glossaire - Programmation#Classe|classes]] qu'il y a quelques variations de cette règle. Ex. ```java void main(){ int heure = 23; if(true){ IO.println(heure); // -> 23 // la variable est déclarée dans un bloc parent : celui de main() { } // elle est accessible depuis le bloc if() { } IO.println(heure); // -> 12 // Déclaration d'une variable dans le bloc if() { } int heureCourante = heure; IO.println(heureCourante); // -> 12 // ne compile pas : la variable est déjà définie dans main(){ } int heure = 14; }// Les variables déclarées dans le bloc if() { } ne sont pas accessible en dehors de celui-ci else { // Déclaration d'une variable dans le bloc else { } int heureCourante = 18; // Ce n'est pas la même qui est déclarée dans le bloc if () { } } // Les variables déclarées dans le bloc else { } ne sont pas accessible en dehors de celui-ci // la variable n'est pas accessible depuis le bloc main() { } heureCourante = 15; IO.println(heure); // -> 23 } ``` Voir [[3.3 - Encapsulation en Java#Portée lexicale (blocs)]] <div style="page-break-after: always;"></div> ### Mot-clé `var` - Inférence de type Si le [[Glossaire - Programmation#Type|type]] d'une [[Glossaire - Programmation#Variable|variable]] n'est pas ambigü, il peut être **[[Glossaire - Programmation#Inférence de type - mot-clé `var`|inferré]]** avec le mor-clé `var` ```java // Les écritures suivantes sont équivalentes String texte = "Hello World!"; var texte = "Hello World!"; ``` ```java // Les écritures suivantes sont équivalentes int entier = 1; var entier = 1; ``` ```java // Les écritures suivantes sont équivalentes double decimal = 3.7; var decimal = 3.7; ``` <div style="page-break-after: always;"></div> ## Structures de contrôle Les **structures de contrôle** 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/ <div style="page-break-after: always;"></div> ## Types de données en Java En Java, il existe 2 familles de types de données. - Les **types primitifs** - Les **types référence** (classes) ### 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 Pour approfondir : - 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 ne pas être initialisés. Ils prennent alors **une valeur par défaut**. > [!tip] Les noms des types primitifs sont écrits en `minuscule` ```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' ``` <div style="page-break-after: always;"></div> ### Types références Les **types références** sont des types de données qui nécessitent une **allocation dynamique de mémoire**. Un certain nombre d'entre-eux sont déjà inclus dans le langage. On peut également créer nos propres types références. Chaque variable d'un type référence est une référence vers un [[Glossaire - Programmation#Objet|objet]]`. - `String` - Types primitifs "boxés" : `Integer` , `Long`, ... - Tableaux (ex. `int[]`) - classes > [!tip] Les noms des types référence commencent toujours par une `Majuscule` Quelques exemples de types références ```java int[] entiers= new int[]{1,2}; String text = "Coda"; ``` Ces types peuvent disposer de **fonctionnalités additionnelles**, qu'on peut accéder par le nom de la variable suivi d'un `.` ```java int[] entiers= new int[]{1,2}; entiers.length; // -> 2 String text = "Coda"; text.length(); // -> 4 text.toLowerCase(); // -> "coda" ``` En java, par défaut les types référence sont muables. Cela signifie qu'on peut en modifier les valeurs internes, même si un type référence est dans une variable `final`. Voir : [[Évolution du langage Java vers l’immuabilité et le non-modifiable]] ## 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; mario.toUpperCase(); // On tente de déréférencer la valeur de mario -> NullPointerException ``` Java ne dispose pas encore de mécanique native pour éviter les valeurs `null` par défaut (contrairement à Kotlin par exemple). Il faudra soigneusement éviter une valeur `null` en initialisant la variable. > [!warning] Les **[[Glossaire - Programmation#Type primitif (Java)|types primitifs]]** ne peuvent pas avoir de valeur `null` https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/ <div style="page-break-after: always;"></div> ## Parenthèse sur la pile et le tas La [[Glossaire - Programmation#Pile (zone de mémoire)|pile]] (stack) est l'espace mémoire contenant les **[[Glossaire - Programmation#Type primitif (Java)|valeurs primitives]]** et permettant au programme de savoir où il en est de l'exécution de celui-ci. Le [[Glossaire - Programmation#Tas (zone de mémoire)|tas]] (heap) est l'espace mémoire utilisé pour les **allocations dynamiques** de mémoire ([[Glossaire - Programmation#Type référence (Java)|valeurs références]]) , 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 <div style="page-break-after: always;"></div> ## `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 ``` <div style="page-break-after: always;"></div> ## Cast (Transtypage) Vous pouvez forcer une conversion (**transtypage**) en précédant une expression par des parenthèses et le type attendu. Les types doivent être compatibles. Ex. `(int) 23.5` Si ce n'est pas le cas, vous obtiendrez une erreur de compilation, ou pire une exception à l'exécution `ClassCastException`. ```javafd double d = 23.76; int i = (int)d; // 23 String foo = (String) 10; // Erreur de compilation : types incompatibles ``` > [!note] > Notez que avoir recours à un transtypage est assez souvent le signe d'une **mauvaise conception** ou imposé par un framework. > > On ne devrait avoir à transtyper que très rarement. <div style="page-break-after: always;"></div> ## Afficher et lire du texte ### À l'ancienne > [!success] Les codes suivants sont compatibles avec toutes les versions de Java 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 > [!warning] Les codes suivants ne fonctionnent que depuis Java 25 et versions supérieures. **Afficher du texte** ```java IO.println("Mon texte avec saut de ligne final"); IO.print("Mon texte sans saut de ligne final") ``` Lire du texte ```java IO.readln() ``` <div style="page-break-after: always;"></div> ## 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 [[2.2 - JShell]]