environnement client/serveur cours 5 rappels java java 8

23
Cours 5 Rappels Java Java 8 Sérialisation [email protected] http://www.lri.fr/~kn ENVIRONNEMENT CLIENT/SERVEUR

Upload: vandan

Post on 05-Jan-2017

232 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Environnement Client/Serveur Cours 5 Rappels Java Java 8

Cours 5 Rappels Java Java 8 Sé[email protected] http://www.lri.fr/~kn

ENVIRONNEMENT CLIENT/SERVEUR

Page 2: Environnement Client/Serveur Cours 5 Rappels Java Java 8

2/23

Plan

1 Rappels sur les systèmes d'exploitations / Communication par mémoire partagée ✔2 Réseaux généralités, IP, UDP ✔3 Multi-thread en Java, TCP ✔4 Broadcast UDP et étude de cas ✔5 Rappels Java/Java 8/Sérialisation

5.1 Rappels Java5.2 Java 85.3 Sérialisation d'objets

Page 3: Environnement Client/Serveur Cours 5 Rappels Java Java 8

3/23

final

une classe :une méthode :

un attribut :

une variable locale ou un paramètre :

Que signifie le mot clé final sur ?

On ne peut pas dériver la classe (ex : String)On ne peut pas redéfinir (override) la méthode. Que signifie redéfinir

?écrire une méthode avec exactement le même prototype dans une

classe dérivée.L'attribut peut être initialisé au plus tard dans le constructeur :si son type est primitif (boolean, char, int, …) alors l'attribut est une

constantesi l'attribut est un objet, alors c'est une référence constante vers cet

objet! (l'état interne de cet objet peut toujours être modifié, cf. lestableaux)

on ne peut pas modifier la valeur de lavariable après initialisation

Page 4: Environnement Client/Serveur Cours 5 Rappels Java Java 8

4/23

Utilité

Contrôle du code utilisateur. Ex: beaucoup de composants de Java (y de sécurité)utilisent la classe String. Si on pouvait dériver la classe et changer ses méthodes (parexemple equals) le code utilisant String n'aurait plus aucune garantie (pour lesclasses et les méthodes final)

Sûreté et documentation : un attribut ou une variable déclarés final ne peuvent êtremodifiés. Le programmeur déclare que ce sont des constantes

Efficacité : un attribut final étant constant, l'optimiseur de la JVM connait sa valeuret faire des optimisations. Une classe ou une méthode final ne pouvant pas êtredérivée/redéfinie, l'optimiseur peut déterminer son code de manière certaine

Page 5: Environnement Client/Serveur Cours 5 Rappels Java Java 8

5/23

finally

(malgré la similitude de nom, ça n'a rien à voir avec final.)

Opération courante : on souhaite écrire dans un fichier, puis le refermer.Cependant, il faut aussi traiter le cas des exceptions correctement :

PrintStream out = …; try {

out.println(…); out.close();

} catch (IOException e) { out.close(); }

Le code de out.close() est dupliqué. Si le code était plus important, ce ne seraitpas maintenable.

Page 6: Environnement Client/Serveur Cours 5 Rappels Java Java 8

6/23

finally

On peut utiliser la clause finally dans un try/catch pour écrire du code qui seraexécuté obligatoirement :

à la fin du bloc, si aucune exception n'est levéeaprès le code du catch si une exception est rattrapéeavant de quitter le bloc (ou la méthode) si l'exception n'est pas rattrapée

PrintStream out = …; try {

out.println(…);

} catch (IOException e) { } finally { out.close(); }

On utilise cette construction lorsque l'on souhaite libérer une ressource (fichier,connexion réseau ou à une base de donnée, …) avant de poursuivre le programme,quelle que soit la manière dont il se poursuit (normalement, exception rattrapée,exception propagée).

Page 7: Environnement Client/Serveur Cours 5 Rappels Java Java 8

7/23

Plan

1 Rappels sur les systèmes d'exploitations / Communication par mémoire partagée ✔2 Réseaux généralités, IP, UDP ✔3 Multi-thread en Java, TCP ✔4 Broadcast UDP et étude de cas ✔5 Rappels Java/Java 8/Sérialisation

5.1 Rappels Java ✔5.2 Java 85.3 Sérialisation d'objets

Page 8: Environnement Client/Serveur Cours 5 Rappels Java Java 8

8/23

Java est enfin un langage fonctionnel

Les interfaces fonctionnelles :Les lambdas-abstraction :La Stream API :

Java 8 apporte des traits fonctionnels au langage. Intérêt de la programmationfonctionnelle :

Code souvent plus compactMeilleure réutilisation du codeCode potentiellement plus efficaceCode souvent plus lisible (si on en a l'habitude)

Trois ingrédients :

Une manière de déclarer le type de fonctionsUne manière de définir des petites fonctions à la volée

Une bibliothèque d'itérateurs efficaces qui vient s'ajouter auxCollections

Page 9: Environnement Client/Serveur Cours 5 Rappels Java Java 8

9/23

Interfaces fonctionnelles

java.util.function.Function<X,Y> :java.util.function.Predicate<X> :

java.util.function.Consumer<X> :

Une interface fonctionnelle est simplement une interface contenant une seuleméthode abstraite. Cette utilisation permet de définir des types de « fonctions ».

représente le type d'une fonction de X vers Yreprésente le type d'une fonction de X vers

booleanreprésente le type d'une fonction de X vers

void

Page 10: Environnement Client/Serveur Cours 5 Rappels Java Java 8

10/23

Exemple

class MyIncr implements Function<Integer,Integer> { //Doit s'appeler apply

Integer apply(Integer x) { return x + 1; } }

class MyOdd implements Predicate<Integer> { //Doit s'appler test

boolean test(Integer x) { return x % 2 == 1; } }

class MyPrint implements Consumer<Integer> { //Doit s'appler accept

void accept(Integer x) { System.out.println(x); } }

Page 11: Environnement Client/Serveur Cours 5 Rappels Java Java 8

11/23

Stream API

Nouvelle API de Java 8. Permet de définir de manière déclarative des itérateurssur des flux. Étant donné un objet qui implémente l'(ancienne) interfaceCollection<E> (par exemple Vector<E>, List<E>, Set<E>) :

Vector<Integer> v = …; … Stream<Integer> s = v.stream();

Que gagne t'on ?

On va pouvoir définir des itérateurs persistants sur les flux, paresseux etparallélisable

Page 12: Environnement Client/Serveur Cours 5 Rappels Java Java 8

12/23

Méthodes de l'interface Stream<T>

.count() :

.skip(long n) :

.limit(long n) :

.distinct() :

.sorted() :

renvoie le nombre d'éléments dans le fluxrenvoie un flux où n éléments ont été sautés

renvoie un flux avec uniquement les n premiers élémentsrenvoie un flux où les doublons (au sens de .equals(Object o) sont

retirésrenvoie un flux où les éléments (qui doivent implémenter Comparable)

son triés

Quelle différence avec les opérateurs sur les Collections ?

Les collections sous-jacentes ne sont pas détruites!

Page 13: Environnement Client/Serveur Cours 5 Rappels Java Java 8

13/23

Méthodes de l'interface Stream<T> (suite)

.filter(Predicate< ? super T> p) :

.allMatch(Predicate< ? super T> p) :

.anyMatch(Predicate< ? super T> p) :

.map(Function< ? super T, ? extends R> f) :

.forEach(Consumer< ? super T> c) :

.collect(…) :

renvoie le flux de tous les éléments pourlesquels le prédicat p renvoie vrai (p peut être défini sur un super-type de T)

renvoie vrai si tous les éléments satisfontle prédicat p

renvoie vrai si un élément satisfait leprédicat p

renvoie le flux d'éléments de typeR obtenu par application de f sur tous les éléments du flux de départ.

applique c tour à tour à tous les éléments duflux.

transforme le flux en Collection. On peut utiliserCollectors.toList(), Collectors.toSet(), …

Page 14: Environnement Client/Serveur Cours 5 Rappels Java Java 8

14/23

Exemple

Supposons que l'on a un vecteur d'Integer v. On souhaite, tous les incrémenter,les trier, puis afficher ceux qui sont impairs :

Vector<Integer> v = … ; v.stream().map(new MyIncr()) .sorted() .filter(new MyOdd()) .forEach(new MyPrint());

Exercice, faire la même chose sans passer par les flux

Page 15: Environnement Client/Serveur Cours 5 Rappels Java Java 8

15/23

λ-abstraction

Il est malcommode de définir les opérations à passer aux itérateurs dans desclasses (MyIncr, …, dans l'exemple précédent). Java 8 fournit une syntaxecommode pour définir des fonctions :

Vector<Integer> v = … ; v.stream().map(i -> i+1) .sorted() .filter(i -> i % 2 == 1) .forEach(i -> System.out.println(i));

La syntaxe générale est :

(Type1 p1, …, Typen pn) -> corps

Le corps peut être soit une expression simple soit un bloc :

(Integer i) -> i+1 (Integer i) -> { System.out.println(i);

Page 16: Environnement Client/Serveur Cours 5 Rappels Java Java 8

16/23

λ-abstraction (suite)

Avantage des λ-abstractions ?

Syntaxe compacte mais lisibleLocalité de la définition (on n'est pas obligé de mettre le code dans une classe

ailleurs)Accès à l'environnement local (à l'inverse des classes anonymes)

PrintWriter out = …; … v.stream().forEach(i -> out.println(i) );

Page 17: Environnement Client/Serveur Cours 5 Rappels Java Java 8

17/23

Que gagne t'on à utiliser la Stream API ?

Persistance : les collections sous-jacentes ne sont pas détruites/modifiées, pasbesoin de faire des copies

Paresse : les opérations ne sont faites que si c'est nécessaire :

Stream<Integer> vs = v.stream().sorted(); if (do_print) vs.forEach(i -> System.out(i)); //le tri n'est fait que si on force (en utilisant .forEach())

Les opérations peuvent se faire le plus possible en parallèle, si on utilise.parallelStream() au lieu de .stream() pour récupérer le flux

implémente le même paradigme que Map/Reduce

Page 18: Environnement Client/Serveur Cours 5 Rappels Java Java 8

18/23

Plan

1 Rappels sur les systèmes d'exploitations / Communication par mémoire partagée ✔2 Réseaux généralités, IP, UDP ✔3 Multi-thread en Java, TCP ✔4 Broadcast UDP et étude de cas ✔5 Rappels Java/Java 8/Sérialisation

5.1 Rappels Java ✔5.2 Java 8 ✔5.3 Sérialisation d'objets

Page 19: Environnement Client/Serveur Cours 5 Rappels Java Java 8

19/23

Pourquoi ?

Une opération courante en informatique est la sérialisation (et désérialisation)des données, c'est à dire passer d'une représentation «en mémoire» à unereprésentation « fichier » (par exemple pour enregistrer dans un fichier ouenvoyer sur le réseau). Pourquoi est-ce nécessaire ? entre autre, à cause despointeurs !

Page 20: Environnement Client/Serveur Cours 5 Rappels Java Java 8

20/23

Sérialisation en Java

Java propose un mécanisme de sérialisation des objets. Chaque objet que l'onveut sauvegarder doit implémenter l'interface : java.io.Serializable C'est une interface vide, traitée spécialement par le compilateur Java. Tout objetqui implémente cette interface peut être sauvegardée dans un flux (fichier,réseau, …) et rechargé ensuite. Les attributs ainsi que le code est sauvegardé.

Beaucoup de classes de la bibliothèque standard implémentent cette interface(tous les types de bases, Integer ,String, …, ainsi que les collections telles queVector, …).

Page 21: Environnement Client/Serveur Cours 5 Rappels Java Java 8

21/23

Lecture/Écriture

ObjectOutputStream :

ObjectInputStream :

On utilise deux classes du package java.io pour lire et écrire des objets :

possède une méthode .writeObject(Object) qui permetd'écrire un objet dans le flux

possède une méthode .readObject() qui permet d'écrire unobjet dans le flux

.readObject() renvoie un Object. On est obligé de faire un cast pour récupérer letype de l'Objet. C'est une opération non sûre !

Si le type de l'objet contient des Generics alors on ne peut pas utiliser instanceofet on obtient un warning du compilateur. On peut supprimer ce dernier avec@SuppressWarning("unchecked")

Page 22: Environnement Client/Serveur Cours 5 Rappels Java Java 8

22/23

Exemple

void save(Vector<String> v) { ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("fichier.obj")); try { out.writeObject(v); } catch (IOException e) { } finally { out.close(); }; }

Vector<String> load() { ObjectInputStream in = new ObjectInputStream( new FileInputStream("fichier.obj")); try { Object o = in.readObject(); @SuppressWarning("unchecked") Vector<String> v = (Vector<String>) o; return v; } catch (IOException e) { } finally { in.close(); };

Page 23: Environnement Client/Serveur Cours 5 Rappels Java Java 8

23/23

Gestion des version

Il est conseillé d'ajouter aux classes sérialisables un attribut

static final long serialVersionUID = 12345L;

Ce dernier peut être généré automatiquement par Eclipse. S'il n'est pas présent lecompilateur Java en insère un automatiquement.

Le runtime Java utilisera cet identifiant pour déterminer qu'un Objet sauvegardéest bien du même type que celui attendu. En particulier il faut changer le numéroquand on ajoute/supprime des champs ou qu'on en change le type.