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