Tour d'horizon de certains éléments de syntaxe et du JDK.
## Hello World
Une [[Glossaire#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 depuis un terminal
```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
[[Glossaire#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]]
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 rarement `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 :
> - [[Glossaire#IDE|IDE]]
> - [[Glossaire#Gestionnaire de dépendances|Gestionnaire de paquet]] comme [[Glossaire#Maven|Maven]] ou [[Glossaire#Gradle|Gradle]]
### Hello World de "boomer"
Dans des versions de Java **plus anciennes que 21-25**, on est obligé d'écrire le programme principal de la façon suivante :
`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 **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#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#Variable|variable]] consiste à [[Glossaire#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`
```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#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 [[3.3 - Encapsulation en Java#Portée lexicale (blocs)]]
### Mot-clé `var` - Inférence de type
Si le [[Glossaire#Type|type]] d'une [[Glossaire#Variable|variable]] n'est pas ambigü, il peut être **[[Glossaire#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;
```
## 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/
## 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'
```
---
### 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#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"
```
---
## 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 marion
// 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.
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#Pile (zone de mémoire)|pile]] (stack) est l'espace mémoire contenant les **[[Glossaire#Type primitif (Java)|valeurs primitives]]** et permettant au programme de savoir où il en est de l'exécution de celui-ci.
Le [[Glossaire#Tas (zone de mémoire)|tas]] (heap) est l'espace mémoire utilisé pour les **allocations dynamiques** de mémoire ([[Glossaire#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
> [!tip]- Stack en musique
> 
## Muabilité et immuabilité
[[Immuabilité et non-modifiable]]
En java, par défaut les types référence sont muables.
Cela signifie qu'on peut en modifier les valeurs internes
## `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) 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
> double d = 23.76;
> int i = (int)d;
> // 23
>
> String foo = (String) 10; // Erreur de compilation : types incompatibles
> ```
>
> 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("Mon texte avec saut de ligne final");
IO.print("Mon texte sans saut de ligne final")
```
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++) {
int number = numbers[i];
System.out.println("Indice " + i + " : " + number);
}
```
Avec une boucle améliorée
```java
int[] numbers = {10, 20, 30, 40, 50};
for (int number : numbers) {
System.out.println("Nombre : " + number);
}
```
```java
String[] couleurs = {"bleu", "vert", "rouge"};
for (String couleur : couleurs) {
System.out.println("Couleur : " + couleur);
}
```
### Arrays
```java
import java.util.Arrays;
```
```java
int[] numbers = new int[5];
Arrays.fill(numbers, 42);
```
Il existe plein d'autres fonctions utilitaires sur les tableaux.
```java
int[] array1 = new int[]{1, 2};
int[] array2 = new int[]{2, 2};
int comparison = Arrays.compare(array1, array2);
System.out.println(comparison);
// -1
// Cela signifie que le tableau 1 {1, 2}
// est inférieur au tableau 2 {2, 2}
```
<!--
- ``
- `Arrays.deepEquals(array2D,new int[][]{{1,2,3}});`
```
- 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
[[2.2 - JShell]]