UE Java 2017-2018 :
- 8 Séances Cours
- 12 Séances de TD/TP
- Disponible en ligne sur Maria Potop-Butucaru
Plan de l’UE :
- Introduction au Java et POO
- Héritage et polymorphisme
- Fiabilité (exceptions, assertions)
- Entrées/Sorties (flux de données, gestion de fichiers, sérialisation,…)
- Programmation réseaux (sockets TCP/UPD)
- Programmation concurrente (multi-threading, synchronisation, interruption)
- Programmation générique, collections et algorithmes
- Bibliothèque graphique (JavaFX)
Notation de l’UE
- 60% Examen final
- 20% Travaux pratiques
- 20% Mini-projet
Le langage Java
Le Langage Java
Langage Orienté Objet statiquement et fortement typé.
Fortement typé: il n’y a pas de conversion implicite entre types.
Statiquement typé: une variable possède un type déterminé à la compilation.
Il s’execute dans un environement d’execution (JavaRuntimeEnvironment)
Une machine virtuelle
Histoire du Java
Le JAVA a été créé en 1991 par des ingénieurs de chez SUN (projet GREEN) pour des applications dédidées aux systèmes embarqués.
Puis, il est utilisé pour développer un navigateur Web en 1995
Ceci permet le developpement d’application Java s’executant dans le navigateur.
Histoire du Java
Dès sa création, il a la particularité de s’exécuter dans une machine virtuelle.
Une fois compilé, un programme Java peut s’exécuter dans n’importe quel environement capable d’exécuter la machine virtuelle.
Historique des versions
1.0 | 1996 | |
1.1 | 1997 | Sérialisation, fichiers JAR, … |
1.2 | 1998 | Collections, … |
1.3 | 2000 | Nouvelle machine virtuelle |
1.4 | 2002 | API I/O, Regex, XML, assert |
5 (1.5) | 2004 | Types génériques, énumérations, for(:) |
6 (1.6) | 2006 | Open source (GPL): OpenJDK |
7 (1.7) | 2011 | switch avec des String, inférence des types, multicatch, Tasks |
8 (1.8) | 2014 | Lambda, stream |
9 (1.9) | 2017 | Support natif json et HTTP/2 |
Version de Java
En plus de l’édition standart (SE), Java propose:
Une version entreprise (EE) qui comprend des librairies supplémentaires, notamment pour des applications très complexes (exécutées sur plusieurs serveurs par exemple)
Une version micro (ME) pour des applications embarquées (librairie pour les communications sans fil, faible consommation, …)
Java vs C++
Java est très proche de C++ dans la syntaxe.
Cependant Java n’utilise pas
- de pointeurs
- de la surcharge d’opérateur
- de l’héritage multiple
La mémoire est gérée automatiquement (la mémoire est libérée par un ramasse miettes).
Java vs C++
Le C++ est compilé en code natif (exécutable), qui ne s’exécute que sur une architecture particulière.
Le Java est compilé en bytecode qui s’exécute sur toutes les architectures (où une machine virtuelle Java est installée).
Le programme est distribué à la fois de manière compilé et portable.
Java vs C++
Le bytecode généré par le compilateur ne dépend pas de l’architecture de la machine où a été compilé le code source, c’est-à-dire que les bytecodes produits sur une machine pourront s’exécuter (via une machine virtuelle) sur des architectures différentes.
Exécution du code Java
Lors de l’exécution d’un programme Java compilé, la machine virtuelle Java JVM:
- Lit le bytecode
- Vérifie qu’il est correct
- Optimise les instructions
- Compile le bytecode en code natif
- Exécute le code natif
On dit que la compilation en code natif est “Just In Time (JIT)”
En résumé
Java produit du code intermédiaire (bytecode) qui est portable. Il est robuste (il est sûr, typé statiquement et fortement) et performant (il est exécuté après une compilation en code natif JIT)
Java et la Programmation Objet
Concept d’Objet
Un programme est constitué de données et de procédures.
La programmation objet consiste à associer au sein d’un objet, les données avec les procédures agissant sur ces données.
Concept d’Objet
Données et procédures indépendantes:
Données:
– modèle
– position
Procédures:
void voiture_recule(Voiture, int)
Concept d’Objet
Données et procédures dans un objet:
Voiture:
– modèle
– position
Methodes :
void avance(int)
void recule(int)
Concept d’Objet
Un objet ne dévoile que ses méthodes publiques (son interface):
Voiture :
void avance(int)
void recule(int)
L’objet maitrise ses données ce qui limite les risques d’effet de bord (lorsqu’un composant modifie les données d’autres composants).
On dit que les données sont encapsulées.
Concept d’Objet
On peut alors utiliser l’objet maVoiture avec la notation suivante:
maVoiture.avance(10);
L’ensemble des méthodes modifiant l’état de maVoiture peuvent être appelées à la suite de maVoiture[point]…
On dit aussi que l’objet maVoiture est de type Voiture
Concept d’Objet
Lorsque l’on programme avec un langage objet, on se pose la question “de quoi est composé notre programme?” et on organise les composants en différents objets.
Séparation des préoccupations
C’est un principe de programmation proposé par E. W. Dijkstra.
Il consiste à découper un programme en plusieurs parties indépendantes, chacun s’occupant d’une tâche. On peut le voir comme un ensemble de modules.
La modularité et la séparation des préoccupations sont obtenues en encapsulant l’information dans une section de code proposant uniquement une interface.
L’encapsulation permet de cacher l’information et le fonctionnement interne d’un module.
Séparation des préoccupations
En Java, les préoccupations sont découpées en objets.
Un objet possède des données qui lui sont propres et met a disposition une interface.
L’interface (l’ensemble des méthodes publiques) permet de modifier l’état de l’objet sans ce soucier de l’implémentation.
Le programme est ainsi plus facile à maintenir et à faire évoluer.
Objets et classes
Il y a plusieurs manières de définir la structure d’un objet
En Java, les Objets sont définis par des classes.
Java va même plus loin car tout est défini par des classes.
Principes de la POO
Principes de la POO
Un objet possède des attributs (des données) et des methodes (des fonctions).
Ces attributs et méthodes peuvent être publics (peuvent être utilisé par d’autres objets) ou privés (caché, ils ne servent que pour le fonctionnement interne de l’objet).
On parle très rarement des attributs privés car leurs caractéristiques (leur nom, leur utilité, leur implémentation) n’ont pas d’importance et peuvent même changer au fil des versions
Principes de la POO
System.out.println("Hello World");
L’objet System
possède un attribut out
. L’objet out
possède une méthode println(). Cette méthode utilise (surement) des attributs et des méthodes privés internes.
On pourra remarquer qu’aucun objet (ou presque) en Java ne possède d’attribut public. En effet, l’encapsulation (“les données sont cachées, et un objet ne laisse apparaitre qu’une interface de haut niveau”) est appliqué à la lettre.
Principes de la POO
Un objet monCompte
représentant un compte bancaire par exemple peut proposer une méthode getBalance()
qui retourne la quantité d’argent sur le compte.
Cette quantité peut être stockée dans l’objet par un attribut privé balance
. Dans ce cas, on dit que getBalance
est un accesseur de l’attribut balance
.
On trouvera parfois une méthode setBalance(int)
permettant de remplacer la valeur de l’attribut privé balance
. Dans ce cas, on dit que setBalance
est un mutateur ou modificateur de l’attribut balance
.
Principes de la POO
Les accesseurs et les modificateurs permettent d’exposer une donnée interne d’un objet. L’interêt et que cette exposition est maitrisée.
Par exemple l’objet monCompte
pourrait proposer comme modificateurs de l’attribut balance
deux méthodes draw(int)
et add(int)
permettant de retirer et ajouter de l’argent. Ces méthodes effectuent des vérifications.
monCompte.getBalance(); // retourne 50
monCompte.draw(30);
monCompte.getBalance(); // retourn 20;
monCompte.draw(30); // erreur, il n'y a pas assez d'argent
monCompte.getBalance(); // retourn 20;
monCompte.add(-30); // erreur, on doit ajouter un nombre positif.
monCompte.getBalance(); // retourn 20;
Instance de Classe
Instance de Classe
Une classe est une manière de décrire un objet (un peu comme un moule).
On peut utiliser une classe pour créer des objets qui auront les attributs et les méthodes décrits par la classe.
Avec une class MonSuperObjet
on peut créer autant d’objets souhaités. On les appelle des Instances de la classe MonSuperObjet.
MonSuperObjet objet1 = new MonSuperObjet();
MonSuperObjet objet2 = new MonSuperObjet();
MonSuperObjet objet3 = new MonSuperObjet();
On instancie la classe lorsqu’on crée une instance de cette classe.
Classe et Objet
Dans une classe on définit les attributs et les méthodes de l’objet.
public class MaSuperClasse {
private String attribut1; // attribut privée
// modificateur public
public void setAttribut1(String a) { /* ... */ }
// accesseur public
public String getAttribut1() { /* ... */ }
// autres méthodes publiques
public void methode1() { /*
Lorsqu'un objet de type MaSuperClasse exécute
methode1(), CET OBJET est modifié de telle façon...
*/
}
// autres méthodes privées
private void methodePrivee1() { /* ... */ }
}
Classe et Objet
Un exemple plus concret :
public class Person {
private String name;
private int birthYear;
// accesseur public
public String getName() { /* ... */ }
// accesseur public
public String getAge() { /* ... */ }
}
Les objets créés avec cette classe possèdent les méthodes définies dans cette classe
Person personne1 = new Person();
Person personne2 = new Person();
personne1.getAge();
personne2.getAge();
Classe et Objet
Une classe permet aussi de définir un constructeur: une fonction appelé lors de la création de l’objet.
public class Person {
private String name;
private int birthYear;
// Constructeur
public Person(String name, int birthYear) { /* ... */ }
public String getName() { /* ... */ }
public String getAge() { /* ... */ }
}
Person alice = new Person("Alice", 1977);
Person bob = new Person("Bob", 1978);
alice.getAge();
bob.getAge();
Constructeur et mot clef this
Un constructeur est surtout utile pour initialiser les attributs privés de l’objets.
Dans une méthode (ou dans le constructeur), l’objet en train d’être manipulé est appelé this
(signifie CET OBJET).
public class Person {
private String name;
private int birthYear;
public Person(String name, int birthYear) {
// Un objet de type Person est en train d'être créé
// Cette objet s'appelle this. A la fin de l'exécution
// de ce constructeur, l'objet this est retourné automatiquement
this.name = name;
this.birthYear = birthYear;
}
/* Reste des méthodes
... */
}
Constructeur et mot clef this
public class Person {
private String name;
private int birthYear;
public Person(String name, int birthYear) {
this.name = name;
this.birthYear = birthYear;
}
public int getAge() {
return 2017 - this.birthYear;
}
}
Person alice = new Person("Alice", 1977);
Person bob = new Person("Bob", 1978);
alice.getAge(); //retourne 40
bob.getAge(); //retourne 39
Lorsqu’on appelle la méthode getAge()
sur un objet, cette objet est appelé this
dans le corps de la méthode.
Lors du 1er appel, this
correspond à l’objet alice
Lors du 2ème appel, il correspond à l’objet bob
.
Constructeur et mot clef this
Lorsqu’il n’ya pas d’ambiguïté, le mot clef this
peut être omis.
public class Person {
private String name;
private int birthYear;
public Person(String name, int birthYear) {
this.name = name;
this.birthYear = birthYear;
}
public int getAge() {
return 2017 - birthYear; // Aucune variable locale ne s'appelle
// birthYear, donc on fait bien référence
// à l'attribut de l'objet courant
}
}
Le Mot Clé final
Le mot-clé final
indique qu’un élément ne peut être changé dans la suite du programme.
Il peut s’appliquer aux méthodes et attributs d’une classe ainsi qu’à la classe elle-même.
Le Mot Clé final
public class Person {
private final String name;
private final int birthYear;
public Person(String name, int birthYear) {
this.name = name;
this.birthYear = birthYear;
}
public int getAge() {
return 2017 - birthYear;
}
public int getName() {
return name;
}
}
Ici ça tombe bien car il n’y a pas de modificateurs.
Lorsqu’un objet ne possède aucun modificateur (son état ne peut pas être modifié après sa création), on dit qu’il est immuable.
l’Objet Classe
l’Objet Classe
Une classe est aussi elle-même un objet.
Elle peut posséder des attributs et des méthodes qu’on appelle attributs de classe et méthodes de classe (ou attributs et méthodes statiques) déclarés avec la mot clé static
.
L’objet classe existe même si la classe n’est pas instanciée.
l’Objet Classe
public class Person {
private final String name;
private final int birthYear;
static private int population = 0;
public Person(String name, int birthYear) {
this.name = name;
this.birthYear = birthYear;
Person.population++;
}
static int getPopulation() {
return population;
}
}
Person.getPopulation(); // return 0
Person alice = new Person("Alice", 1977);
Person.getPopulation(); // return 1
alice.getPopulation(); // return 1
l’Objet Classe
public class Personne {
private final String name;
private final int birthYear;
static private int population = 0;
static final public int majority = 18;
public Person(String name, int birthYear) {
this.name = name;
this.birthYear = birthYear;
Person.population++;
}
public int getAge() {
return 2017 - birthYear;
}
static int getPopulation() {
return population;
}
public boolean isAdult() {
return getAge() >= majority;
}
}
Personne.majority; // return 18
Personne alice = new Personne("Alice", 1977);
alice.isAdult(); // return true
l’Objet Classe
System.out.println("Hello World");
out
est un attribut statique de type PrintStream
de la classe System
.
println(String)
est une méthode publique de la classe PrintStream
Notions de Base du Java
Déclaration des variables
// types primitifs
int a = 5, b = 3;
char c;
// Objets
LocalDateTime currentTime;
currentTime = LocalDateTime.now();
Scanner sc = new Scanner(System.in);
Les instructions simples
int a = 5, b = 3;
int sum;
sum = a + b;
System.out.println(a + "+" + b + "=" + sum);
double quot = a / (double)b;
System.out.println(a + "/" + b + "=" + quot);
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("Current DateTime: " + currentTime);
Conditions
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
if(i % 2 == 1) {
System.out.println("Odd");
} else {
System.out.println("Even");
}
Conditions
String s = System.getProperty("os.name");
switch(s) {
case "Linux":
// Execute something for Linux
case "Mac OS X":
// Execute something for Mac OS X
case "FreeBSD":
// Execute something for FreeBSD
//...
default:
// Otherwise
}
Boucles
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
while (i >= 0){
if(i % 2 == 1) {
System.out.println("Odd");
} else {
System.out.println("Even");
}
i = sc.nextInt();
}
Boucles
Scanner sc = new Scanner(System.in);
boolean stop = false;
do {
int i = sc.nextInt();
if(i < 0) {
stop = true;
} else if(i % 2 == 1) {
System.out.println("Odd");
} else {
System.out.println("Even");
}
} while (!stop);
Boucles
Scanner sc = new Scanner(System.in);
do {
int i = sc.nextInt();
if(i < 0) {
break;
}
if(i % 2 == 1) {
System.out.println("Odd");
} else {
System.out.println("Even");
}
} while (true);
Boucles
for(int i = 1; i < 11; ++i) {
System.out.println(i+"² = "+(i*i));
}
Boucles
String mail = "quentin.bramas@lip6.fr";
for (String part : mail.split("[^\\w]")) {
System.out.println(part);
}
Une application simple
Premier programme
Un programme est défini dans une classe, par une méthode statique et public nommée main
// Ce code ce trouve dans un fichier portant le même nom que la classe: MonProgramme.java
public class MonProgramme {
public static void main(String[] args) {
System.out.println("hello world");
}
}
Execution du programme
La compilation s’effectue avec la commande
javac MonProgramme.java
L’execution du programme s’effectue avec la commande
java MonProgramme
Les plateformes pour les TPs
Outils de Développement
JDK Java SE 8
Editeur : NetBeans – Eclipse – IntelliJ IDEA – Atom