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