Académique Documents
Professionnel Documents
Culture Documents
• Principe de base
Nous allons coder une classe Solo. Celle-ci va travailler avec des références de type String. Voici le
diagramme de classe de cette dernière en figure suivante.
La classe Solo permet d’affecter une valeur, la mettre à jour et la récupérer… Maintenant, si je vous
demande de me faire une classe qui permet de travailler avec n'importe quel type de données
Programmation générique
Cast obligatoire
Vous serez donc sans doute tentés d'écrire une classe par type de donnée (SoloInt, SoloString ,
etc.). Et c'est là que la généricité s'avère utile, car avec cette dernière, vous pourrez savoir ce que
contient votre objet Solo et n'aurez qu'une seule classe à développer
Programmation générique
public class Solo<T> {
• Principe de base (suite 2)
//Variable d'instance
Objet générique private T valeur;
public static void main(String[] args) { //Retourne la valeur déjà « castée » par la signature de la méthode !
Solo<Integer> val = new Solo<Integer>(12); public T getValeur(){
int nbre = val.getValeur(); return this.valeur;
} }
}
Programmation générique
public class Duo<T, S> {
//Variable d'instance de type T
private T valeur1;
• Principe de base (suite 3) //Variable d'instance de type S
La généricité peut être multiple private S valeur2;
Accolades après
l’instanciation
Le nouveau soin n'est définie que pour cet objet. Nous devons seulement redéfinir la (ou les) méthode(s) de
l'interface ou de la classe abstraite dans un bloc d'instructions ; d'où les accolades après l'instanciation.
Les classes Anonymes
Utiliser une classe anonyme revient à créer une classe fille sans être obligé de créer cette classe de façon
explicite. L'héritage se produit automatiquement. La classe créée n'a pas de nom, l'héritage s'effectue de
façon implicite !
Nous bénéficions donc de tous les avantages de la classe mère en ne redéfinissant que la méthode qui
nous intéresse.
Les classes anonymes sont soumises aux mêmes règles que les classes « normales » :
• Utilisation des méthodes non redéfinies de la classe mère ;
• Obligation de redéfinir toutes les méthodes d'une interface ;
• Obligation de redéfinir les méthodes abstraites d'une classe abstraite.
Cependant, ces classes possèdent des restrictions à cause de leur rôle et de leur raison d'être :
• Elles ne peuvent pas être déclarées abstract ;
• Elles ne peuvent pas non plus être déclarées static ;
• Elles ne peuvent pas définir de constructeur ;
• Elles sont automatiquement déclarées final : on ne peut dériver de cette classe, l'héritage est donc
impossible !
Les interfaces et java 8
Java 8 permet aux interfaces de définir des méthodes avec un comportement par défaut et de définir des méthodes
statiques.
Méthodes statiques :
Une interface est une classe 100% abstraite, ce n'est plus le cas depuis Java 8 car cette interface est valide et ce code
fonctionne parfaitement :
Les interfaces et java 8
Le code de test ci-dessous donne le résultat
Méthodes statiques (suite): ci-après
Nous pouvons même rajouter un niveau d'interface
supplémentaire
Les interfaces et java 8
Méthode par défaut :
depuis Java 8, il est possible d'ajouter un comportement par
défaut à des méthodes dans une interface grâce au mot
clé default
Je suis un alien et :
Je ponds des oeufs !
Je me divise
Les interfaces et java 8
Méthode par défaut (suite):
Il est à présent possible de bénéficier d'un comportement par défaut dans des méthodes d'interfaces.
Ceci permet notamment d'assurer une compatibilité à vos interfaces si vous souhaitez rajouter des méthodes
dans celles-ci. En effet, dans un projet informatique de taille, vous aurez tout un tas d'interfaces et rajouter
une méthode dans une interface voulais dire, avant Java 8 et les méthodes par défaut, repasser sur toutes les
classes qui implémentent l'interface afin de redéfinir la nouvelle méthode : ce n'est plus la peine avec java 8.
En résumé
• Avec Java 8, une interface n'est plus une classe 100% abstraite.
• Elle peut contenir des méthodes concrètes sous deux formes :
• Avec des méthodes statiques;
• Avec une définition par défaut d'une méthode.
Les interfaces fonctionnelles (depuis java 8)
Ce concept permet de définir une interface n'ayant qu'une et une seule méthode abstraite
Dans notre exemple précédent, notre interface Soin est une interface fonctionnelle car elle n'a qu'une
méthode à redéfinir (Single Abstract Method, ou interface SAM).
Ce type d'interface sera le pilier de l'utilisation des lambdas
Pour s'assurer que le contrat est bien respecté, Java propose d'annoter l'interface
avec @FunctionalInterface , comme ceci :
Avec l annotation, Java vous
indiquera qu'il y a un
problème
Les interfaces fonctionnelles
Mais vous avez tout à fait le droit d'avoir une interface fonctionnelle avec des méthodes par défaut, comme
le montre l'image ci-dessous :
Java 8 vient avec de nombreuses interfaces fonctionnelles prédéfinies dans le package java.util.function dont
le détail est disponible à l'adresse suivante :
https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Les Lambdas (depuis java 8)
Avant Java 8, il n’existait que deux types de références, des valeurs primitives (char c = 'C‘) et des références
vers des objets (String s = new String("Hello").
Dans d'autres langages par contre, il existe des références vers ce qu'on appelle des closures : des morceaux de
codes anonymes.
Jusqu'en Java 7, la seul façon d'avoir ce type de référence revenait a faire une classe anonyme comme vu
précédemment. Depuis Java 8, les closures existent et s'appellent les lambdas.
Pour simplifier au maximum, une lambda est la redéfinition d'une méthode d'une interface fonctionnelle sans
avoir à faire une classe anonyme, donc gain de ligne de code et de visibilité.
Il existe des dérivées de ces interfaces qui spécifient un peut plus leur fonctionnement.
Par exemple il existe une interface IntFunction dont la signature de la méthode apply est la suivante :
R apply(int value). L'interface renverra un type générique mais prendra un entier en paramètre.
Il existe un bon nombre de ces interfaces et, en général, elles sont présentent pour chaque type mentionné sur
le slide précèdent.
En voici une liste non exhaustive IntFunction, IntSupplier, IntBinaryOperation,
IntConsumer, IntToDoubleConsumer, IntToDoubleFunction, …
Et ce code nous donne le résultat suivant :
Le package java.util.function : java.util.function.Function<T,R>
[toto, titi, tata, tutu]
[20, 40, 60, 80]
Le package java.util.function : java.util.function.Function<T,R> (suite)
Il est aussi possible de surcharger une méthode par défaut de ces interfaces fonctionnelles. Par exemple,
dans celle que nous venons d'utiliser, il y a la méthode addThen qui permet d'appliquer une fonction
après le traitement. Par exemple, nous obtenons exactement le même résultat que précédemment avec ce
code :
Le package java.util.function : java.util.function.Consumer<T>
Encore plus simple que la précédente interface car celle-ci ne retourne rien, elle se contente de "consommer"
un objet, donc d'y appliquer un traitement, comme par exemple ajouter 13 ans à l'age d'un objet Personne.
La méthode qui va être implémenter dans l'interface fonctionnelle par ce biais devra
correspondre à la signature de la méthode abstraite.
Pour simplifier au maximum, une référence de méthode est une lambda ultra simplifiée en
utilisant ni plus ni moins qu'une méthode déjà existante dans une interface (méthode
statique) classe (méthode statique ou constructeur) ou encore une méthode d'une instance
de classe. Voici comment la syntaxe est faite :
« classe, interface ou instance » :: « Nom de la méthode »
Voir les exemples ci après (nous en profiterons pour voir d'autres interfaces fonctionnelles
présentes dans Java 8)
Les références de méthodes (suite)
Le code ci-après nous fournit la sortie suivante :
0.1234567
0.1234567
Bonjour !
Bonjour !
New Integer created : class java.lang.Integer
L’API Stream de java 8
Le concept de Stream existe déjà depuis longtemps dans l'API I/O, notamment avec les interfaces InputStream et
OutputStream.
Il ne faut pas confondre l'API Stream de Java 8 avec les classes de type xxxStream de Java I/O.
Les streams de Java I/O permettent de lire ou écrire des données dans un flux (sockets, fichiers, ...). Le concept de Stream
de Java 8 est différent du concept de flux (stream) de l'API I/O même si l'approche de base est similaire : manipuler un flux
d'octets ou de caractères pour l'API I/O et manipuler un flux de données pour l'API Stream.
Cette dernière repose sur le concept de flux (stream en anglais) qui est une séquence d'éléments.
L'API Stream facilite l'exécution de traitements sur des données de manière séquentielle ou parallèle.
Les Streams permettent de laisser le développeur se concentrer sur les données et les traitements réalisés sur cet ensemble
de données sans avoir à se préoccuper de détails techniques de bas niveau comme l'itération sur chacun des éléments ou
la possibilité d'exécuter ces traitements de manière parallèle.
L'API Stream de Java 8 propose une approche fonctionnelle dans les développements avec Java. Elle permet de décrire de
manière concise et expressive un ensemble d'opérations dont le but est de réaliser des traitements sur les éléments d'une
source de données. Cette façon de faire est complètement différente de l'approche itérative utilisée dans les traitements
d'un ensemble de données avant Java 8.
Un Stream permet d'exécuter une agrégation d'opérations de manière séquentielle ou en parallèle sur une
séquence d'éléments obtenus à partir d'une source dans le but d'obtenir un résultat.
Java 7 propose le framework Fork/Join pour faciliter la mise en œuvre de ces opérations en parallèle.
L'API Stream utilise ce framework pour l'exécution des traitements en parallèle.
L’API Stream de java 8 (suite)
L'utilisation de l'API Stream possède donc plusieurs avantages :
- L'exécution, sur un ensemble de données, de traitements définis de manière déclarative
- La quantité de code à produire pour obtenir un traitement similaire reposant sur sa propre itération est réduite
- La possibilité d'exécuter ses traitements en parallèle
L’API Stream de java 8 (suite)
L’API Stream de java 8 (suite)
parallelStream
We will also look at some of the core classes of the new Java 8 project that are part of the java.time package, such
as LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Period, Duration and their supported APIs (voir exemples).
Thread safety – The Date and Calendar classes are not thread safe, leaving developers to deal with the headache of hard-
to-debug concurrency issues and to write additional code to handle thread safety. On the contrary, the
new Date and Time APIs introduced in Java 8 are immutable and thread safe, thus taking that concurrency headache away
from developers.
API design and ease of understanding – The Date and Calendar APIs are poorly designed with inadequate methods to
perform day-to-day operations. The new Date/Time API is ISO-centric and follows consistent domain models for date, time,
duration and periods. There are a wide variety of utility methods that support the most common operations.
ZonedDate and Time – Developers had to write additional logic to handle time-zone logic with the old APIs, whereas with
the new APIs, handling of time zone can be done with Local and ZonedDate/Time APIs.
la nouvelle API de gestion des dates de Java 8
Exemples
la nouvelle API de gestion des dates de Java 8
Exemples
Java FX
• Bibliothèque Graphique
• Intégrée dans JRE et JDK
• Permet de réaliser des interfaces graphiques évoluées :
– Animations
– Effets
– 3D
– Audio
– Vidéo
Notez que la méthode de démarrage (start) est abstraite et doit être surchargée. Les
méthodes d'initialisation (init) et d'arrêt (stop) ont des implémentations concrètes qui
ne font rien.
Java FX
Java FX
Java FX
Java FX
Java FX
Exemple
Java FX
Les évènements
Dans les applications JavaFX, les événements signifient que quelque chose s'est produit : un utilisateur a cliqué sur
un bouton, appuie sur une touche, déplace une souris ou effectue d'autres actions, …
Dans JavaFX, un événement est une instance de la classe javafx.event.Event ou de toute sous-classe d'Event.
JavaFX fournit plusieurs sous-classe d'Event, notamment DragEvent, KeyEvent, MouseEvent, ScrollEvent et
d'autres.
Java FX
Exemple complet
Java FX
Java FX vs Swing
JavaFX Cons:
- not quite as mature in terms of getting all the bugs out
- no "system" look and feel
- not truly built-in until Java 8 you must use java 8 or greatest
JavaFX Pros:
- cleaner API, much easier to work with
- CSS styling
- built-in animation system
- property system and bindings are great
- media support (e.g. video player)
- significant effort and investment from Oracle.
- Execution plus rapide (à mesurer )
Swing Cons:
- customizing look is more difficult (unless you are picking a pre-made look and feel)
- APIs are less consistent
- no built-in data-binding concept
Swing Pros:
- system look and feel (though some find it is not a close enough match, e.g. file chooser)
- stable and proven
Le framework Fork/Join de Java 7
Comprendre la réflexivité
JVM modulaire avec Java 9