☕ Java#

Indication
Cette page à pour but de découvrir le langage Java, sa librairie standard, quelques concepts de base de l’OOP et quelques outils bien utiles.
Bref histoire de Java#
Nous devons l’existence du langage et de la technologie Java à (feu) Sun Microsystems, celle-ci fût également à l’origine d’autres avancées.
Sun Microsystems#

- 1982
Création de Sun,
- 1987
Standardisation d”UNIX System V,
- 1995
Technologie Java
- 1999 - 2008
StarOffice, Solaris, VirtualBox, MySQL, Java DB (depuis Apache Derby) etc.
- 2009
Acquisition de Sun Microsystems par Oracle Corporation pour 5.6 Milliard USD.
- Pourquoi un nouveau langage comme Java ?
Au début des années 1990, le langage le plus utilisé au sein de Sun est C++.
Dans le même moment, Patrick Naughton envisage une migration du parc de machines vers NeXT. Le besoin d’un nouveau framework de développement applicatif se fait sentir.
C’est le début du projet « Stealth » qui devient par la suite Green Projet avec l’arrivée de James Gosling et de Mike Sheridan.
- Pourquoi abandonner le C++ ?
La compléxité du langage est une source d’erreurs pour les novices,
La gestion de la mémoire reste complexe avec l’absence de ramasse-miettes,
- Les papas de Java estime que le langage posséde trop de « lacunes » (qui sont en réalité les lacunes des développeurs)
Problèmes de sécurité
Difficulté de mise en oeuvre de programme distribuée
Difficulté à mettre en place le multi-threading
- Quels sont les approches envisagées ?
James Gosling envisage de modifier et d’améliorer C++ pour en faire C++ ++ - (ce n’est pas une blague)
Bill Joy envisage de développer un nouveau langage combinant le meilleur de Mesa et du C et de le nommer Further (plus loin).
- Et voilà le projet Oak (chêne)
Le projet se nomme ainsi en référence à un arbre devant les fenêtres du bureau de Sun.
En 1992, démonstration de l’OS Green et du langage Oak
En 1994, Changement de nom pour Java (Oak étant utilisé par un fabricant de carte vidéo)
- Pourquoi ce nom de Java ?
Selon la légende ce nom est trouvé dans un bar (évidemment) par quelques membres de l’équipe.
Soit il s’agit de l’acronyme J ames Gosling, A rthur V an Hoff et A ndy Bechtolsheim,
Soit de l’acronyme J ust A nother V ague A cronym (juste un acronyme vague de plus)
- L’avénement par la suite de Java 2
2000, apparition des J2SE (Java 2 Standard Edition) depuis JAVA SE et J2EE (Java 2 Enterprise Edition) depuis JAVA EE.
200x, la JVM est améliorée et SWING apparaît comme une alternative à .NET.
2006-2007, Arrivé du JDK (JRE et les outils de développement), du compilateur javac, passage en Open Source de JavaEE.
2007-2008, développement d”Android par Google.
2009, rachat de Sun par Oracle.
La philosophie du langage Java#
Java se veut simple, orienté objet et familier. De plus celui-ci a vocation à être sûr et robuste, indépendant de la plateforme pour l’exécution et surtout performant. A cette liste se rajoute le fait d’être compilé, multi-tâches et dynamique.
- Un ramasse-miettes ?
En anglais Garbage Collector, il s’agit d’une sous-routine appelé régulièrement et automatiquement durant l’exécution du programme. Celle-ci retire au dev la tâche de gérer la mémoire (allocation et libération). Il est possible de lui « suggérer » de se lancer via
System.gc
- Indépendant vis à vis de la plateforme
Le langage fourni des bibliothèques standard (graphismes, réseau, etc.) qui fonctionnent de la même manière sur toutes les architectures. Des compilateurs Java sont fournies et compilent le code source « à moitié » afin d’obtenir un bytecode Java. Le bytecode est un langage de type assembleur proche de la machine et spécifique à la plateforme Java. Celui a besoin d’être interprété par la JVM (Java Virtual Machine).
- Bytecode
Il s’agit d’un langage de type assembleur proche de la machine et spécifique à la plateforme Java et à sa JVM.
- Cycle de vie d’un programme Java
Ecriture du fichier de code source .java
Compilation de celui-ci en .class
Interprétation du .class par la JVM
Quelques bases de Java#
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello World !") ;
}
}
$ javac HelloWorld.java
$ EXPORT CLASSPATH = .
$ java HelloWorld
Mots réservés, primitifs et littéraux#

int count = 0;
boolean flag = true;
char mychar = 'S';
System.out.println("Hello World");
System.out.println(count);
System.out.println(flag);
System.out.println(mychar);
Array en Java#
int[] arrInt = new int[10];
int[] arrInt = new int[10];
int arrInt[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
arrInt.lenght;
arrInt[4] = 2;
Note
Les index vont de 0 à taille - 1;
Un tableau ne peut être redimensionné;
Chaque élément du tableau prend sa valeur par défaut.
Collections de taille variable#
La classe Abstraite AbstractList
est fournie pour implémenter les collections de taille variable.
int index = 0;
ArrayList list = new ArrayList();
list.add(12);
list.get(index);
list.size();
list.remove(index);
Un peu de syntaxe en Java#
while (true) { } //ceci est ignoble
for (int value = 0; value < 42; value++) { }
for (int value : list) { }
if (flag){
//do something
}else if(!flag){
//do something
}else{ /* impossible, why ? */
//do something
}
switch(value){
case 1:
// do something
break;
case 2:
// do something
break;
default:
// do something
break;
}
Exceptions#
Une exception est une erreur se produisant dans un programme qui conduit le plus souvent à l’arrêt de celui-ci. Un exemple plus que répandu dans le monde Java NullReferenceException
.
int a = 20;
int b = 0;
System.out.println(a/b);
>>> Exception in thread "main"
>> java.lang.ArithmeticException: / by zero
int a = 20, b = 0 ;
try{
System.out.println(a/b) ;
}catch(ArithmeticException ex){
System.out.println(String.format("Error %s", e.getMessage()));
}finally{
System.out.println("ALWAYS EXECUTE");
}
Packages#
Chaque package porte un nom, ce nom est soit un simple identificateur ou une suite d’identificateurs séparés par des points.
package mesozoic;
Si nous avons besoin d’une classe en dehors du package de notre classe, il faut l’importer ainsi:
import paquet.subpaquet;
Les Strings en Java#
String name = "Kenobi";
System.out.println(name);
name = System.console().readLine();
System.out.println(name);
Scanner in = new Scanner(System.in);
int i = in.nextInt();
String s = in.next();
À faire
Réaliser un simple programme de type Hello World pour vérifier le fonctionnement de votre environnement de développement.
Indication
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
À faire
Écrivez un programme simple permettant de calculer une masse à différents endroits du système solaire. Pour ce faire nous allons stocker une masse arbitraire de 42 dans une variable de type double.
Sur mercure il suffit de multiplier cette valeur par 0.378, sur la lune par 0.166 et sur Jupiter par 2.364. La sortie de votre programme doit produire un affichage semblable :
The mass of the object on Earth is 42.0.
The mass of the object on Mercury is 15.876.
The mass of the object on the Moon is 6.972.
The mass of the object on Jupiter is 99.288.
Améliorer le programme en demandant à l’utilisateur d’entrer la valeur de la masse au sein de la console.
À faire
Nous allons écrire un programme de « benchmarking » très simple. Pour ce faire nous allons compter le nombre de tours que fait une boucle infinie sur un intervalle de temps donnée à savoir une minute.
Indication
long v_Time = System.currentTimeMillis( ) ;
// Permet d'obtenir le timestamp courant
v_Time += 1000; // Ajout d'une secode
break ; // Pour interrompre un programme , une boucle, ..
À faire
La compagnie des treizes nains
String[] v_Dwarfs = {"Thorin",
"Balin", "Dwalin", "Fili", "Kili",
"Dori", "Nori", "Ori", "Oin", "Gloin",
"Bifur", "Bofur", "Bombur" };
Afficher la taille du tableau
Afficher les élèments du tableau un à un
Afficher les élèments du tableau et la longueur de chacun
- Réaliser le même exercice en remplaçant le tableau de String par un ArrayList puis :
Rajouter Bilbo Baggins à cette joyeuse compagnie
Afficher les élèments de la liste un à un
Retirer Thorin, Fili et Kili de la liste
Des objects en Java#
Les objets sont créer en utilisant une classe
comme template.
public class Human {
}
public class Human {
private String quote = "May the force be with you";
}
public class Human {
private String quote = "May the force be with you";
public String talk() {
return this.quote;
}
}
Human ben, vader;
ben = new Human();
vader = new Human();
ben.talk(); // May the force be with you
vader.quote = "Join me!"; // ?
public class Human {
public void setQuote(String quote){
this.quote = quote;
}
public String getQuote(){
return this.quote;
}
}
public class Human {
private String firstname;
private String lastname;
public Human(String firstname, String lastname, String quote)
{
this.firstname = firstname;
this.lastname = lastname;
this.quote = quote;
}
}
public class Human {
@Override
public String toString()
{
}
}
Signature de méthodes#
Grâce au signature, on peut adapter le comportement de nos méthodes:
public class Human {
public String talk(String sentence)
{
return sentence;
}
}
Attribut de classe, une mémoire collectif#
Grâce au signature, on peut adapter le comportement de nos méthodes:
public class Human {
private static int alive = 0;
public int getAlive(){
return alive;
}
}
Héritage, transmettre son patrimoine#
public class Jedi extends Human {
}
Indication
Il est possible d’empêcher la dérivation
final public class Jedi extends Human {
}
Object class, la mère de toutes les classes
public class Human {
public String getSuperClassName() {
return getClass()
.getSuperClass().getName();
}
}
Le polymorphisme en Java#
Note
Le polymorphisme c’est l’identification à l’exécution du code qui doit être exécuté.
public class Creature {
public String talk(){
return "Hello World";
}
}
public class Human extends Creature {
}
public class Hobbit extends Creature {
public String talk() {
return "In a hole in the ground there lived a hobbit.";
}
}
Human human = new Human();
Creature creature = new Creature();
Hobbit hobbit = new Hobbit();
human.talk(); // output ?
creature.talk(); // output ?
hobbit.talk(); //output ?
creature = hobbit;
human.talk(); // output ?
Méthodes et classes abstraites#
Quand il est nécessaire d’intégrer une méthode dans une classe pour laquelle on ne peut pas fournir du code, la solution a adopter est la création d’une classe abstraite.
Note
Si une classe contient une méthode abstraitre alors celle-ci doit être abstraite.
Il n’est alors pas possible de l’instancier, elle permet de définir un état générique et un comportement générique.
public abstract class Creature {
public abstract String talk();
}
public class Hobbit extends Creature {
public String talk(){
return "In a hole in the ground there lived a hobbit.";
}
}
Interfaces et classe java#
Par définition, une classe correspond à une structure possédant un nom, des données et qui offre des opérations.
Souvent on utilise uniquement une classe pour les services rendus par celle-ci i.e. à son interface.
Les interfaces permettent d’apporter un comportement commun entre différentes classes sans lien d’héritage.
Note
Une interface contient uniquement des signatures de méthodes, de propriétés, etc.;
Une interface contient des définitions pour un groupe de fonctionnalités connexes qu’une classe peut implémenter.
Exemple d’une interface en UML#
Par convention les noms d’interfaces commencent par un
I
.Toute classe qui implémente une interface doit contenir une définition pour chaque méthode définit au sein de l’interface.
L’interface ne définit pas la méthode ! Elle ne fournit que la signature.
Exemple d’implémentation d’une interface en UML#
Les membres d’une interface sont automatiquement publics, non statiques. Pour implémenter un membre d’interface, le membre correspondant de la classe doit être public, non statique et porter le même nom et la même signature.
Important
Quand une classe implémente une interface, elle doit fournir une implémentation pour l’ensemble des membres définit au sein de l’interface.
L’interface n’offre aucune fonctionnalité dont une classe peut hériter à la manière de l’héritage, toutefois si une classe mère implémente une interface, alors les classes filles bénéficient de cette implémentation.
Note
Une interface est semblable à une classe abstraite dans laquelle toutes les méthodes sont abstraites.
En revanche, une classe peut implémenter plusieurs interfaces, mais une classe peut uniquement hériter d’une seule classe, abstraite ou non.
public interface ITalker {
String talk();
}
public class Hobbit implement ITalker {
public String talk(){
return "In a hole in the ground there lived a hobbit.";
}
}
À faire
Nous nous inspirerons de l’univers d’un jeu vidéo bien connu à savoir Warcraft.

- Nous allons créer une première classe « Peon ». -
Celle-ci doit contenir les attributs permettant d’identifier le péon (son nom), ses points de vie et ses points de mana.
- Elle doit également fournir
un constructeur par défaut,
un constructeur paramétré,
une surcharge de la méthode toString
ainsi qu’une méthode talk permettant de faire parler l’unité dont la signature est la suivante
public void talk()
.
L’une des caractéristiques des unités dans Warcraft est leurs phrases devenues cultes prononcés lors de leurs sélections par le joueur. Nous allons donc ajouter un attribut à notre classe qui sera une collection de différentes phrases.
Lors de l’appel à la méthode talk, l’une de ces phrases devra être sélectionnée « aléatoirement » pour varier un peu les paroles de l’unité.
Indication
public static int randInt(int min, int max){
Random rand = new Random();
return rand.nextInt((max - min) + 1) + min;
}
Important
N’oublier pas les getters, setters et le nommage des packages.
Avec un seul type d’unité notre jeu risque d’être passablement ennuyeux. Il convient donc d’ajouter de nouveaux types d’unité.
- Ajoutons une nouvelle classe que nous appellerons
Grunt
. Avant de vous jeter sur votre IDE, il convient de prendre le temps de réfléchir quelque peu à la conception de notre projet. La classe
Peon
et:code:Grunt partagent de nombreux points communs.
- Ajoutons une nouvelle classe que nous appellerons
Nous allons pouvoir rassembler tous ces attributs et méthodes communes au sein d’une classe mère que nous nommerons
Unit
.- Créer une classe mère dont les classes
Peon
etGrunt
hériteront. Vous êtes libres des attributs et méthodes que vous jugerez utiles de créer, - toutefois celle-ci doit au moins posséder les attributs suivants:
Nom (name),
Race (race),
Point de vie (HP),
Point de force (minimunDamage),
Point de chance (randomDamage),
Porté (range),
Point d’armure (armor),
Est en vie (isAlive)
- Ainsi que les méthodes suivantes:
public abstract String talk();
public void dance();
- Créer une classe mère dont les classes
Nous avons créé des unités pour la race des orcs, pourquoi ne pas en créer quelques-unes pour les humains à savoir Peasant
et Footman
.
Diagramme UML de classe Warcraft#
Pour faire interargir nos unités il faut leur fournir des contrats à remplir.
Créer une simple interface
isOrganic
qui contient un attributi_isPoissoned
et une méthodebool isPoissoned();
. Cette interface devra être implémentée au sein des classes que nous avons créées précédemment.L’interface précédente était un simple entrainement pour vous familiariser avec la syntaxe des interfaces. Les choses sérieuses commencent ici avec l’implémentation d’une interface
isWarrior
.Cette interface permet de faire combattre nos unités, pour celle-ci doit fournir une méthode
public void attack(Unit p_Unit)
:
Indication
On vérifie bien évidemment si l’unité est encore en vie.
Calcul des dégats si Point de chance = 0:
v_Damage = minimumDamage * (1 - unit.getArmor() / 10).
Calcul des dégats si Point de chance != 0:
v_Damage = randInt(minimumDamage, randomDamage) * (1 - unit.getArmor() / 10).
Il serait judicieux d’ajouter une méthode dans la classe Unit pour absorber les dégâts.
Maven#
Apache Maven est un outil pour la gestion et l’automatisation de production des projets logiciels Java en général et Java EE en particulier.
L’objectif recherché est comparable au système make
sous Unix:
produire un logiciel à partir de ses sources;
en optimisant les tâches réalisées à cette fin et;
en garantissant le bon ordre de fabrication.
Celui-ci se base sur l’utilisation d’un fichier pom.xml
(Project Object Model).
Chaque projet est configuré via un fichier pom.xml
qui contient les informations nécessaires à Maven pour traiter le projet:
nom du projet;
numéro de version;
dépendances vers d’autres projets;
bibliothèques nécessaires à la compilation;
noms des contributeurs;
etc.
<?xml version="1.0" encoding="UTF-8"?>
<project>
<dependencies>
</dependencies>
<build>
</build>
</project>
<dependencies>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.18.0</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
Une première application utile en Java#
Attention
Une application java créer via maven ne fournit pas de main
par défaut, assurez vous de le créer et que votre application fonctionne avant de passer à la suite.
Nous allons tenter de développer une (mini/nano) première application (un peu) utile en java.
Notre programme appellera une API qui va récupérer le résultat de la requête en JSON (JavaScript Object Notation) pour l’afficher dans notre console.
Les API sur Internet
Les API sont un moyen d’accéder aux données d’un site sans avoir l’autorisation d’accéder directement à la base de données. Il y a beaucoup de portails sécurisés permettant à vos applications web de manipuler les données renvoyées par ces sites.
L’exemple parfait est Twitter. Elle permet de lire la timeline d’une personne en particulier, de rechercher des statuts à partir d’un mot clé, de modifier les paramètres de votre compte, etc.
Pourquoi le format JSON ?
Vous pouvez utiliser les API avec de nombreux langages et retourner les données de plusieurs façons. L’une d’elles est le JSON (JavaScript Object Notation). C’est un format de données léger, facile à lire et à écrire et compatible avec pas mal de langages de développement.
Sa structure est composée d’objets et de tableaux. Sa flexibilité fait de JSON le parfait candidat pour retourner des données.
D’abord il convient d’installer unirest.
Puis dans notre main
nous pouvons appeller l’api suivante https://ingen.ugaritic.fr/api/books :
GetRequest getResponse = Unirest.get("https://ingen.ugaritic.fr/api/books/");
JsonNode body = getResponse.asJson().getBody();
System.out.println(body());
System.out.println(getResponse.asJson().getStatus());
JSONArray books = body.getArray();
for(int i = 0; i < books.length(); i++)
{
JSONObject book = books.getJSONObject(i);
System.out.println(book.getString("title"));
System.out.println(book.getInt("year"));
}
À faire
Modifiez votre
main
pour afficher chaque élément (titre, auteur, etc.) retourné par l’API,Essayez de récupérer l’élément JSON à l’url suivante: /api/books/a-game-of-thrones comme précédemment.
À faire
En utilisant l’api suivante https://ingen.ugaritic.fr/api/dinosaurs:
Diagramme UML de classe#
Créer une classe
DinosaursAPI
permettant de récupérer l’ensemble des dinosaures;Chaque dinosaure devra être injecter dans un objet java (une instance de la classe
Dinosaur
);Créer une seconde méthode qui permet de récupérer plus d’information sur un dinosaure précis (sélection via un menu console ?).
Tests unitaires en Java#
Le but de cette partie est d’implanter la loi d’Ohm en utilisant l’approche TDD.
La loi d’Ohm ?
C’est une loi physique empirique qui lie l’intensité du courant électrique traversant un dipôle électrique à la tension à ses bornes. Cette loi permet de déterminer la valeur d’une résistance. La loi d’Ohm a été ainsi nommée en référence au physicien allemand Georg Simon Ohm qui la publie en 1827, dans son œuvre Die galvanische Kette: mathematisch bearbeitet.
Énoncé de la loi d’Ohm
On note :
\(U\) la tension aux bornes de la résistance ;
\(I\) l’intensité du courant qui circule à travers la résistance ;
\(R\) la valeur de la résistance.
La loi d’Ohm établit que : \(U = R \times I\)

Utilisation de la loi
Selon son expression et les grandeurs connues, la loi d’Ohm permet d’obtenir différentes grandeurs :
sous la forme \(U = R \times I\), elle permet de calculer la tension lorsque la résistance et l’intensité sont connues;
sous la forme \(I = U \div R\), elle permet de calculer l’intensité lorsque la tension et la résistance sont connues;
sous la forme \(R = U \div I\), elle permet de calculer la résistance lorsque la tension et l’intensité sont connues.
Nous allons créer la classe OhmLaw
ainsi que la signature des méthodes (nous n’allons pas encore les implémenter). Pour le corps des méthodes utiliser:
throw new UnsupportedException();
Diagramme UML de classe OhmLaw#
Créer une classe héritant de JUnitTest
en utilisant le menu contextuelle et en filtrant les items par le mot test
.
package delahayeyoursel.physic;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class OhmLawTest {
public OhmTest() {
}
@BeforeAll
public static void setUpClass() {
}
@AfterAll
public static void tearDownClass() {
}
@BeforeEach
public void setUp() {
}
@AfterEach
public void tearDown() {
}
@Test
public void testCalculer()
{
assertEquals(, LoiOhm.calculer); //TODO complete this line
}
}
À faire
À vous de jouer ! Tester les trois méthodes de la classe OhmLaw
puis implanter ces méthodes.
Les flux d’entrée/sortie (IO)#
Une entrée/sortie en Java consiste en un échange de données entre le programme et une autre source (mémoire, fichier, le programme lui-même etc.)
En Java on utilise des objets spécifiques appellés « Stream ».
Toute opération sur les IO doit suivre le schéma suivant:
Ouverture
Lecture ou Écriture
Fermeture
Il existe deux catégorie de flux:
Les objets travaillant avec des flux d’entrées (
in
) lectureLes objets travaillant avec des flux de sorties (
out
) écriture
File file = new File("readme.md");
file.getAbsolutePath();
file.getName();
file.exists();
file.isDirectory();
file.isFile();
FileInputStream et FileOutputStream#
FileInputStream fis = null;
BufferedInputStream bis = null;
byte[] bytes = new byte[8];
fis = new FileInputStream(filepath);
bis = new BufferedInputStream(fis);
while(bis.read(bytes) > 0){
for(byte b : bytes){
String format = String.format("\t %s - (%s)", b, (char)b);
System.out.println(format);
bytes = new byte[8];
}
}
if(bis != null){
bis.close();
}
if(fis != null){
fis.close();
}
FileInputStream fis = null;
BufferedInputStream bis = null;
DataInputStream dis = null;
fis = new FileInputStream(filepath);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
while (dis.available() != 0) {
System.out.println(dis.readLine());
}
dis.close();
bis.close();
fis.close();
Avertissement
Tout cela est déprécié ! Pas d’inquiétude, il s’agit de l’ancienne méthode encore bien répandu.
Depuis Java 8 et l’arrivée du package java.nio
, on passera par l’utilisation de classe utilitaire, ce qui nous simplifie la lecture et l’écriture de fichiers et notamment avec la fermeture automatique des flux.
Path path = Paths.get("/home/sam/readme.md");
Stream<String> lines = Files.lines(path);
List<String> content;
content = lines.collect(Collectors.toList());
for(String line : content){
System.out.println(line);
}
Path path = Paths.get("/home/sam/readme.md");
List<String> newLines = Arrays.asList("Darth Vader", "Darth Sidious");
Files.write(path, newLines);
Indication
En mode APPEND
Files.write(path, newLines, StandardOpenOption.APPEND);
ObjectInputStream et ObjectOutputStream#
La sérialisation
Lorsqu’on veut écrire des objets dans des fichiers, on utilise la sérialisation « représentation d’un objet sous la forme d’un String ».
public class Dinosaur implements Serializable{
protected String name;
public Dinosaur(String name){
this.name = name;
}
}
Note
Serializable
est ce qu’on appelle une interface marqueur.
Path path = Paths.get("/home/sam/readme.md");
FileOutputStream fileOutputStream = new FileOutputStream(path.toFile());
try(ObjectOutputStream oos = new ObjectOutputStream(fileOutputStream)){
oos.writeObject(marie);
}
FileInputStream fileInputStream = new FileInputStream(path.toFile());
try(ObjectInputStream ois = new ObjectInputStream(fileInputStream)) {
Dinosaur dinosaur = (Dinosaur) ois.readObject();
System.out.println(dinosaur);
}
Danger
Si notre classe contient une instance d’un objet non sérialisable. Si c’est le cas il faut spécifier que l’objet ne doit pas êtré sérialisée via transient
.
public class Dinosaur implements Serializable{
protected transient String name;
public Dinosaur(String name){
this.name = name;
}
}
À faire
Avertissement
Nos programmes jusqu’alors utilise la mémoire vive de notre machine pour stocker des données sous la forme d’instances, de listes, etc.
Il est donc temps de lire et d’écrire dans des fichiers avec Java.
Récupérer le fichier
perceval.txt
;Créer une méthode statique au sein d’une classe
Perceval
permettant de récupérer l’ensemble des citations contenu dans le fichier;Afficher l’ensemble des citations dans la console.
Créer un programme qui écrit dans un fichier
courses.txt
la liste de vos courses;Celui-ci fonctionne dans une boucle de saisie, par exemple tant que l’utilisateur n’a pas saisie exit on continue la saisie de course;
Si l’élément est déjà présent dans la liste on affiche cette information à l’utilisateur;
Sinon on ajoute l’élément dans la liste;
Adopter une démarche objet pour réaliser cet exercice.
À faire
Créer une classe Compteur
qui respecte le diagramme UML suivant:
Diagramme UML de classe Counter#
Créer une méthode pour sauvegarder une instance de compteur au sein d’un fichier.
Créer une méthode pour récuperer une instance de compteur depuis un fichier.
SWING#
Nous avons pour l’instant créé uniquement des applications console. Nous allons désormais créer des interfaces graphiques pour permettrent aux utilisateurs d’interagir plus facilement avec notre programme.
En Java il existe plusieurs librairies pour créer des interfaces graphiques:
AWT
: Abstract Window Toolkit, emploie les composants natif de la plateforme;SWING
: Utilise AWT comme base, offre la possibilité de créer des GUI identitques quelque soit le SE;JavaFX
: apparu avec Java8 en mars 2014, une pure API Java qui ne décolle pas ou peu.

La JFrame
est le composant de base de toute GUI
public class MainFrame extends JFrame{
public MainFrame(){
this.setTitle("HelloHobbitTown");
this.setSize(300, 200);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
Auquel nous pouvons ajouté des composants:
public MainFrame(){
JPanel toolbar = new JPanel();
JButton button = new JButton("Hello World");
toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));
toolbar.add(button);
this.add(toolbar);
}
et enfin un gestionnaire d’événements:
public class MainFrame extends JFrame implements ActionListener{
public MainFrame(){
button.addActionListener((ActionListener) this);
}
@Override
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(this, "In a hole in the ground lived a Hobbit");
}
}
À faire

Créer une application basique qui permet de compter;
Penser à séparer le code de l’interface et le code métier (celui du compteur).

Modifier l’application précédente pour ajouter un champ de saisie qui permet lors du clique sur le bouton salutations d’afficher une boîte de dialogue;
Penser encore une fois à séparer le code de l’interface et le code métier.
Nous allons créer un jeu très simple: le plus ou moins. Le but est de deviner en un minimum de coup un chiffre aléatoire entre une borne min et une borne max.

Créer le projet de cette application;
Séparer le code métier du code de l’interface;
Pour commencer utiliser un intervalle compris entre 0 et 10 cela sera plus simple.
JDBC#
JDBC (Java DataBase Connectivity) permet aux applications Java d’accéder par le biais d’une interface commune à des sources de données pour lesquelles il existe des pilotes JDBC.
Contenu dans deux packages:
java.sql
etjavax.sql
.

L’exécution de requête SQL se fait par l’utilisation de Statement
:
Statement
: Requête simple sur le SGBD(R) sans passage de paramètres;PreparedStatement
: Requête préparée pour éviter les injections SQL;CallableStatement
: Utiliser pour éxécuter une procédure stockée au sein du SGBD(R).
Pour se connecter au SGBDR, dans notre cas il faut d’abord charger le connecteur JDBC. Dans notre cas SQLite, il ne faut utiliser le package xerial/sqlite-jdbc.
String sqlite3path = String.format("jdbc:sqlite:%s", "/home/sam/cards.sqlite3");
Class.forName("org.sqlite.JDBC");
Connection connection = DriverManager.getConnection(sqlite3path);
String query = "SELECT * FROM decks;";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
int id = 42;
String query = "SELECT * FROM decks WHERE id = (?);";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, id);
ResultSet resultSet = preparedStatement.executeQuery();
while(resultSet.next()){
String deckName = resultSet.getString("name");
int deckId = resultSet.getInt("id");
}
resultSet.close();
statement.close(); // preparedStatement.close();
connection.close();
Rendez-vous sur le site du driver sqlite pour récupérer la dépendance à ajouter dans votre fichier pom.xml
.
<dependencies>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.7.2</version>
</dependency>
</dependencies>
Une fois cela fait nous pouvons commencer à utiliser l’interface JDBC.
Vous pouvez récupérer une base de données de comptes bancaires à cette adresse
.
Diagramme UML de classe Account#
À faire
Créer une méthode dans la classe
Account
pour récupérer l’ensemble des comptes de la base de données, vous utiliserez bien entendu le constructeur de la classeAccount
pour créer un objet de typeAccount
pour chaque enregistrement;Créer une méthode dans la classe
Account
pour récupérer un seule enregistrement par son identifiant.Afficher l’ensemble des comptes au sein de la console.
Afficher le compte n°42.
Créer une méthode dans
Account
pour créer un nouvelle enregistrement;- Ajouter un enregistrement avec les informations suivantes:
Kenobi
Ben
04/05/1977
GB24QMSJ6083124321466
4792716002601180
VISA 19 digit
06/28
8642
Créer une méthode pour mettre à jour un enregistrement;
Mettre à jour l’enregistrement précédent avec comme balance 666;
Mettre à jour l’enregistrement précédent avec comme prénom Obi-Wan;
Créer une méthode pour supprimer un enregistrement via son id;
Supprimer l’enregistrement précédent.
Design Pattern#
Un patron de conception (ou design pattern) est un arrangement caractéristique de modules, reconnu comme bonne pratique en réponse à un problème de conception d’un logiciel.
Il décrit une solution standard, utilisable dans la conception de différents logiciels. Il en existe de nombreux dont on peut citer: Factory, Decorator, Iterator, Observer, Singleton, etc.
public final class DatabaseManager {
private static volatile DatabaseManager instance = null;
private DatabaseManager() {
super();
}
public final static DatabaseManager getInstance() {
if (null == instance) {
instance = new DatabaseManager();
}
return instance;
}
}
Mini Projet Java « CODEX »#
raichement diplômé, vous venez de vous lancer en freelance sur le marché du développement applicatif et vous venez de signer votre premier contrat.
Votre client souhaite obtenir à l’issue de votre travail une application du type CODEX lui permettant de lister les éléments d’une base de données.
Attention
Seul la consultation de la base est demandée, si vous souhaitez intégrer plus de fonctionnalités cela sera bien évidemement valorisé.
Il vous est demandé de réaliser une application de type client lourd en Java en utilisant la technologie Swing et le SGBD SQLite comme vu durant les TDs.
La base de données vous est fourni par le client: Ingen database
.
Indication
Voici un exemple de l’interface que vous pouvez réaliser

Lecture d’images depuis la BDD
Les images sont stockées au sein de la base SQLite sous forme de blob.
Voici un exemple de code Java pour convertir un blob en objet de type Image
import java.awt.Toolkit;
Toolkit.getDefaultToolkit().createImage(resultSet.getBytes("image"));
Pour redimensionner une image utiliser la méthode getScaledInstance
Une image peut être afficher au sein d’un label vide
Image image = ...;
imageLabel.setIcon(new ImageIcon(image));
Une JList
est un composant SWING qui affiche une liste d’objets. Il suffit de la configurer pour que celle-ci accepte un type d’objet différents de celui par défaut.
Pour ouvrir une boîte de dialogue qui permet de sélectioner un fichier, vous pouvez utiliser le JFileChooser
.
JFileChooser jFileChooser = new JFileChooser();
jFileChooser.setDialogTitle("Select image file");
jFileChooser.setAcceptAllFileFilterUsed(false);
FileNameExtensionFilter filter = new FileNameExtensionFilter("Image", "png", "jpg");
jFileChooser.addChoosableFileFilter(filter);
int returnValue = jFileChooser.showOpenDialog(this);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = jFileChooser.getSelectedFile();
}