Cours Java gestion des bases de données avec l’API JDBC, tutoriel & guide de travaux pratiques langage Java en pdf.
Lecture de données tapées au clavier
Le flux de données provenant du clavier est désigné par l’objet System.in de type InputStream. Ce type d’objets permet de lire des données caractère par caractère. C’est au programmeur de retrouver ensuite dans ce flux de caractères les informations qui l’intéressent. Le type InputStream ne permet pas de lire d’un seul coup une ligne de texte. Le type BufferedReader le permet avec la méthode readLine.
Afin de pouvoir lire des lignes de texte tapées au clavier, on crée à partir du flux d’entrée System.in de type InputStream, un autre flux d’entrée de type BufferedReader cette fois :
BufferedReader IN=new BufferedReader(new InputStreamReader(System.in));
Nous n’expliquerons pas ici les détails de cette instruction qui fait intervenir la notion de constructions d’objets. Nous l’utiliserons telle-quelle.
La construction d’un flux peut échouer : une erreur fatale, appelée exception en Java, est alors générée. A chaque fois qu’une méthode est susceptible de générer une exception, le compilateur Java exige qu’elle soit gérée par le programmeur. Aussi, pour créer le flux d’entrée précédent, il faudra en réalité écrire :
BufferedReader IN=null;
try{
IN=new BufferedReader(new InputStreamReader(System.in));
} catch (Exception e){ System.err.println(« Erreur » +e); System.exit(1);
}
De nouveau, on ne cherchera pas à expliquer ici la gestion des exceptions. Une fois le flux IN précédent construit, on peut lire une ligne de texte par l’instruction :
String ligne;
ligne=IN.readLine();
La ligne tapée au clavier est rangée dans la variable ligne et peut ensuite être exploitée par le programme.
Exemple d’entrées-sorties
Voici un programme d’illustration des opérations d’entrées-sorties clavier/écran :
import java.io.*; public class io1{
// nécessaire pour l’utilisation de flux d’E/S
public static void main (String[] arg){
écriture sur le flux System.out Object obj=new Object(); System.out.println(« »+obj); System.out.println(obj.getClass().getName());
écriture sur le flux System.err
int i=10;
System.err.println(« i= »+i);
lecture d’une ligne saisie au clavier String ligne;
BufferedReader IN=null; try{
IN=new BufferedReader(new InputStreamReader(System.in)); } catch (Exception e){
affiche(e); System.exit(1);
}
System.out.print(« Tapez une ligne : « ); try{
ligne=IN.readLine(); System.out.println(« ligne= »+ligne);
} catch (Exception e){ affiche(e); System.exit(2);
}
}//fin main
public static void affiche(Exception e){
System.err.println(« Erreur : « +e);
}
}//fin classe
et les résultats de l’exécution :
C:\Serge\java\bases\iostream>java io1
java.lang.Object@1ee78b
java.lang.Object
i=10
Tapez une ligne : je suis là
ligne=je suis là
Les instructions
Object obj=new Object();
System.out.println(« »+obj);
System.out.println(obj.getClass().getName());
ont pour but de montrer que n’importe quel objet peut faire l’objet d’un affichage. Nous ne chercherons pas ici à expliquer la signification de ce qui est affiché. Nous avons également l’affichage de la valeur d’un objet dans le bloc :
try{
IN=new BufferedReader(new InputStreamReader(System.in)); } catch (Exception e){
affiche(e);
System.exit(1);
}
La variable e est un objet de type Exception qu’on affiche ici avec l’appel affiche(e). Nous avions rencontré, sans en parler, cet affichage de la valeur d’une exception dans le programme de conversion vu plus haut.
Affectation de la valeur d’une expression à une variable
On s’intéresse ici à l’opération variable=expression;
L’expression peut être de type : arithmétique, relationnelle, booléenne, caractères
Interprétation de l’opération d’affectation
L’opération variable=expression; est elle-même une expression dont l’évaluation se déroule de la façon suivante :
La partie droite de l’affectation est évaluée : le résultat est une valeur V.
la valeur V est affectée à la variable
la valeur V est aussi la valeur de l’affectation vue cette fois en tant qu’expression.
C’est ainsi que l’opération V1=V2=expression est légale. A cause de la priorité, c’est l’opérateur = le plus à droite qui va être évalué. On a donc V1=(V2=expression). L’expression V2=expression est évaluée et a pour valeur V. L’évaluation de cette expression a
provoqué l’affectation de V à V2. L’opérateur = suivant est alors évalué sous la forme V1=V . La valeur de cette expression est
encore V. Son évaluation provoque l’affectation de V à V1. Ainsi donc, l’opération V1=V2=expression est une expression dont
l’évaluation
1 provoque l’affectation de la valeur de expression aux variables V1 et V2
2 rend comme résultat la valeur de expression.
On peut généraliser à une expresion du type : V1=V2=….=Vn=expression
Expression arithmétique
Les opérateurs des expressions arithmétiques sont les suivants :
addition
soustraction
multiplication
division : le résultat est le quotient exact si l’un au moins des opérandes est réel. Si les deux opérandes sont entiers le résultat est le quotient entier. Ainsi 5/2 -> 2 et 5.0/2 ->2.5.
division : le résultat est le reste quelque soit la nature des opérandes, le quotient étant lui entier. C’est donc l’opération modulo.
Comparaison de deux caractères
Soient deux caractères C1 et C2. Il est possible de les comparer avec les opérateurs <, <=, ==, !=, >, >=
Ce sont alors leurs codes ASCII, qui sont des nombres, qui sont alors comparés. On rappelle que selon l’ordre ASCII on a les relations suivantes :
espace < .. < ‘0’ < ‘1’ < .. < ‘9’ < .. < ‘A’ < ‘B’ < .. < ‘Z’ < .. < ‘a’ < ‘b’ < .. <‘z’
Comparaison de deux chaînes de caractères
Elles sont comparées caractère par caractère. La première inégalité rencontrée entre deux caractères induit une inégalité de même sens sur les chaînes.
Exemples :
Soit à comparer les chaînes « Chat » et « Chien »
Cette dernière inégalité permet de dire que « Chat » < « Chien ».
Soit à comparer les chaînes « Chat » et « Chaton ». Il y a égalité tout le temps jusqu’à épuisement de la chaîne « Chat ». Dans ce cas, la chaîne épuisée est déclarée la plus « petite ». On a donc la relation
« Chat » < « Chaton ».
Fonctions de comparaisons de deux chaînes
On ne peut utiliser ici les opérateurs relationnels <, <=, ==, !=, >, >= . Il faut utiliser des méthodes de la classe String :
String chaine1, chaine2;
chaine1=…;
chaine2=…;
int i=chaine1.compareTo(chaine2);
boolean egal=chaine1.equals(chaine2)
Ci-dessus, la variable i aura la valeur :
si les deux chaînes sont égales
si chaîne n°1 > chaîne n°2
-1 si chaîne n°1 < chaîne n°2
La variable egal aura la valeur true si les deux chaînes sont égales.
Expressions booléennes
Les opérateurs sont & (and) ||(or) et ! (not). Le résultat d’une expression booléenne est un booléen.
ordre de priorité !, &&,||
exemple :
int fin;
int x;
fin= x>2 && x<4;
Les opérateurs relationnels ont priorité sur les opérateurs && et ||.
Traitement de bits
Les opérateurs
Soient i et j deux entiers.
i<<n décale i de n bits sur la gauche. Les bits entrants sont des zéros.
i>>n décale i de n bits sur la droite. Si i est un entier signé (signed char, int, long) le bit de signe est préservé.
i & j fait le ET logique de i et j bit à bit.
i | j fait le OU logique de i et j bit à bit.
~i complémente i à 1
i^j fait le OU EXCLUSIF de i et j
Soit
int i=0x123F, k=0xF123;
unsigned j=0xF123;
opération valeur
i<<4 0x23F0
i>>4 0x0123 le bit de signe est préservé.
k>>4 0xFF12 le bit de signe est préservé.
i&j 0x1023
i|j 0xF33F
~i 0xEDC0
Combinaison d’opérateurs
a=a+b peut s’écrire a+=b
a=a-b peut s’écrire a-=b
Il en est de même avec les opérateurs /, %,* ,<<, >>, &, |, ^
Ainsi a=a+2; peut s’écrire a+=2;
Opérateurs d’incrémentation et de décrémentation
La notation variable++ signifie variable=variable+1 ou encore variable+=1 La notation variable– signifie variable=variable-1 ou encore variable-=1.
L’opérateur ?
L’expression expr_cond ? expr1:expr2 est évaluée de la façon suivante :
l’expression expr_cond est évaluée. C’est une expression conditionnelle à valeur vrai ou faux
Si elle est vraie, la valeur de l’expression est celle de expr1. expr2 n’est pas évaluée.
Si elle est fausse, c’est l’inverse qui se produit : la valeur de l’expression est celle de expr2. expr1 n’est pas évaluée.
Exemple
i=(j>4 ? j+1:j-1);
affectera à la variable i :
j+1 si j>4, j-1 sinon
C’est la même chose que d’écrire if(j>4) i=j+1; else i=j-1; mais c’est plus concis.
La structure d’un programme Java
Un programme Java n’utilisant pas de classe définie par l’utilisateur ni de fonctions autres que la fonction principale main pourra avoir la structure suivante :
public class test1{
public static void main(String arg[]){
code du programme }// main
}// class
La fonction main, appelée aussi méthode est exécutée la première lors de l’exécution d’un programme Java. Elle doit avoir obligatoirement la signature précédente :
public static void main(String arg[]){
ou
public static void main(String[] arg){
Le nom de l’argument arg peut être quelconque. C’est un tableau de chaînes de caractères représentant les arguments de la ligne de commande. Nous y reviendrons un peu plus loin.
Si on utilise des fonctions susceptibles de générer des exceptions qu’on ne souhaite pas gérer finement, on pourra encadrer le code du programme par une clause try/catch :
public class test1{
public static void main(String arg[]){
try{
… code du programme
} catch (Exception e){
gestion de l’erreur }// try
}// main
}// class
Au début du code source et avant la définition de la classe, il est usuel de trouver des instructions d’importation de classes. Par exemple :
import java.io.*;
public class test1{
public static void main(String arg[]){
code du programme }// main
}// class
Prenons un exemple. Soit l’instruction d’écriture suivante :
System.out.println(« java »);
qui écrit java à l’écran. Il y a dans cette simple instruction beaucoup de choses :
System est une classe dont le nom complet est java.lang.System
out est une propriété de cette classe de type java.io.PrintStream, une autre classe
println est une méthode de la classe java.io.PrintStream.
Nous ne compliquerons pas inutilement cette explication qui vient trop tôt puisqu’elle nécessite la compréhension de la notion de classe pas encore abordée. On peut assimiler une classe à une ressource. Ici, le compilateur aura besoin d’avoir accès aux deux classes java.lang.System et java.io.PrintStream. Les centaines de classes de Java sont réparties dans des archives aussi appelées des paquetages (package). Les instruction import placées en début de programme servent à indiquer au compilateur de quelles classes externes le programme a besoin (celles utilisées mais non définies dans le fichier source qui sera compilé). Ainsi dans notre exemple, notre programme a besoin des classes java.lang.System et java.io.PrintStream. On le dit avec l’instruction import. On pourrait écrire en début de programme :
import java.lang.System;
import java.io.PrintStream;
Un programme Java utilisant couramment plusieurs dizaines de classes externes, il serait pénible d’écrire toutes les fonction import nécessaires. Les classes ont été regroupées dans des paquetages et on peut alors importer le paquetage entier. Ainsi pour importer les paquetages java.lang et java.io, on écrira :
import java.lang.*;
import java.io.*;
Le paquetage java.lang contient toutes les classes de base de Java et il est importé automatiquement par le compilateur. Aussi finalement n’écrira-t-on que :
import java.io.*;
La gestion des exceptions
De nombreuses fonctions Java sont susceptibles de générer des exceptions, c’est à dire des erreurs. Nous avons déjà rencontré une telle fonction, la fonction readLine :
String ligne=null;
try{
ligne=IN.readLine();
System.out.println(« ligne= »+ligne);
} catch (Exception e){ affiche(e); System.exit(2);
}// try
Lorsqu’une fonction est susceptible de générer une exception, le compilateur Java oblige le programmeur à gérer celle-ci dans le but d’obtenir des programmes plus résistants aux erreurs : il faut toujours éviter le « plantage » sauvage d’une application. Ici, la fonction
readLine génère une exception s’il n’y a rien à lire parce que par exemple le flux d’entrée a été fermé. La gestion d’une exception se fait selon le schéma suivant :
try{
appel de la fonction susceptible de générer l’exception } catch (Exception e){
traiter l’exception e
}
instruction suivante
Si la fonction ne génère pas d’exception, on passe alors à instruction suivante, sinon on passe dans le corps de la clause catch puis à instruction suivante. Notons les points suivants :
e est un objet dérivé du type Exception. On peut être plus précis en utilisant des types tels que IOException, SecurityException, ArithmeticException, etc… : il existe une vingtaine de types d’exceptions. En écrivant catch (Exception e), on indique qu’on veut gérer toutes les types d’exceptions. Si le code de la clause try est susceptible de générer plusieurs types d’exceptions, on peut vouloir être plus précis en gérant l’exception avec plusieurs clauses catch :
try{
appel de la fonction susceptible de générer l’exception } catch (IOException e){
traiter l’exception e
}
} catch (ArrayIndexOutOfBoundsException e){ traiter l’exception e
}
} catch (RunTimeException e){ traiter l’exception e
}
instruction suivante
On peut ajouter aux clauses try/catch, une clause finally :
try{
appel de la fonction susceptible de générer l’exception
} catch (Exception e){ traiter l’exception e
}
finally{
code exécuté après try ou catch
}
instruction suivante
Ici, qu’il y ait exception ou pas, le code de la clause finally sera toujours exécuté.
La classe Exception a une méthode getMessage() qui rend un message détaillant l’erreur qui s’est produite. Ainsi si on veut afficher celui-ci, on écrira :
catch (Exception ex){
System.err.println(« L’erreur suivante s’est produite : « +ex.getMessage());
…
}//catch
La classe Exception a une méthode toString() qui rend une chaîne de caractères indiquant le type de l’exception ainsi que la valeur de la propriété Message. On pourra ainsi écrire :
catch (Exception ex){
System.err.println (« L’erreur suivante s’est produite : « +ex.toString());
…
}//catch
On peut écrire aussi :
catch (Exception ex){
System.err.println (« L’erreur suivante s’est produite : « +ex);
…
}//catch
Nous avons ici une opération string + Exception qui va être automatiquement transformée en string + Exception.toString() par le compilateur afin de faire la concaténation de deux chaînes de caractères.
L’exemple suivant montre une exception générée par l’utilisation d’un élément de tableau inexistant :
tableaux
imports import java.io.*;
public class tab1{
public static void main(String[] args){
déclaration & initialisation d’un tableau int[] tab=new int[] {0,1,2,3};
int i;
affichage tableau avec un for
for (i=0; i<tab.length; i++)
System.out.println(« tab[ » + i + « ]= » + tab[i]);
génération d’une exception try{
tab[100]=6; }catch (Exception e){
System.err.println(« L’erreur suivante s’est produite : » + e); }//try-catch
}//main
}//classe
L’exécution du programme donne les résultats suivants :
tab[0]=0
tab[1]=1
tab[2]=2
tab[3]=3
L’erreur suivante s’est produite : java.lang.ArrayIndexOutOfBoundsException
Voici un autre exemple où on gère l’exception provoquée par l’affectation d’une chaîne de caractères à un nombre lorsque la chaîne ne représente pas un nombre :
imports import java.io.*;
public class console1{
public static void main(String[] args){
création d’un flux d’entrée BufferedReader IN=null;
try{
IN=new BufferedReader(new InputStreamReader(System.in)); }catch(Exception ex){}
// On demande le nom
lecture réponse String nom=null; try{
nom=IN.readLine(); }catch(Exception ex){}
on demande l’âge int age=0; boolean ageOK=false; while ( ! ageOK){
question System.out.print(« âge : « );
lecture-vérification réponse try{
age=Integer.parseInt(IN.readLine());
ageOK=true; }catch(Exception ex) {
System.err.println(« Age incorrect, recommencez… »); }//try-catch
}//while
// affichage final
System.out.println(« Vous vous appelez » + nom + » et vous avez » + age + » ans »); }//Main
}//classe
Quelques résultats d’exécution :
dos>java console1
Nom : dupont
âge : 23
Vous vous appelez dupont et vous avez 23 ans
E:\data\serge\MSNET\c#\bases\1>console1
Nom : dupont
âge : xx
Age incorrect, recommencez…
âge : 12
Vous vous appelez dupont et vous avez 12 ans
Compilation et exécution d’un programme Java
Soit à compiler puis exécuter le programme suivant :
importation de classes import java.io.*;
classe test
public class coucou{
// fonction main
public static void main(String args[]){
affichage écran System.out.println(« coucou »);
}//main
}//classe
Le fichier source contenant la classe coucou précédente doit obligatoirement s’appeler coucou.java
E:\data\serge\JAVA\ESSAIS\intro1>dir 10/06/2002 08:42 228 coucou.java
La compilation et l’exécution d’un programme Java se fait dans une fenêtre DOS. Les exécutables javac.exe (compilateur) et java.exe (interpréteur) se trouvent dans le répertoire bin du répertoire d’installation du JDK :
E:\data\serge\JAVA\classes\paquetages\personne>dir « e:\program files\jdk14\bin\java?.exe »
07/02/2002 12:52 24 649 java.exe
07/02/2002 12:52 28 766 javac.exe
Le compilateur javac.exe va analyser le fichier source .java et produire un fichier compilé .class. Celui-ci n’est pas immédiatement exécutable par le processeur. Il nécessite un interpréteur Java (java.exe) qu’on appelle une machine virtuelle ou JVM (Java Virtual Machine). A partir du code intermédiaire présent dans le fichier .class, la machine virtuelle va générer des instructions spécifiques au processeur de la machine sur laquelle elle s’exécute. Il existe des machines virtuelles Java pour différents types de systèmes d’exploitation (Windows, Unix, Mac OS,…). Un fichier .class pourra être exécuté par n’importe laquelle de ces machines virtuelles donc sur n’importe que système d’exploitation. Cette portabilité inter-systèmes est l’un des atouts majeurs de Java.
1. LES BASES DU LANGAGE JAVA
1.1 INTRODUCTION 7
1.2 LES DONNEES DE JAVA
1.3 LES INSTRUCTIONS ELEMENTAIRES DE JAVA
1.4 LES INSTRUCTIONS DE CONTROLE DU DEROULEMENT DU PROGRAMME
1.5 LA STRUCTURE D’UN PROGRAMME JAVA
1.6 LA GESTION DES EXCEPTIONS
1.7 COMPILATION ET EXECUTION D’UN PROGRAMME JAVA
1.8 ARGUMENTS DU PROGRAMME PRINCIPAL
1.9 PASSAGE DE PARAMETRES A UNE FONCTION
1.10 L’EXEMPLE IMPOTS
2. CLASSES ET INTERFACES
2.1 L’ OBJET PAR L’EXEMPLE
2.2 L’HERITAGE PAR L’EXEMPLE
2.3 CLASSES INTERNES
2.4 LES INTERFACES
2.5 CLASSES ANONYMES
2.6 LES PAQUETAGES
2.7 L’EXEMPLE IMPOTS
3. CLASSES D’USAGE COURANT
3.1 LA DOCUMENTATION
3.2 LES CLASSES DE TEST
3.3 LA CLASSE STRING
3.4 LA CLASSE VECTOR
3.5 LA CLASSE ARRAYLIST
3.6 LA CLASSE ARRAYS
3.7 LA CLASSE ENUMERATION
3.8 LA CLASSE HASHTABLE
3.9 LES FICHIERS TEXTE
3.10 LES FICHIERS BINAIRES
3.11 UTILISER LES EXPRESSION REGULIERES
3.12 EXERCICES
4. INTERFACES GRAPHIQUES
4.1 LES BASES DES INTERFACES GRAPHIQUES
4.2 CONSTRUIRE UNE INTERFACE GRAPHIQUE AVEC JBUILDER
4.3 BOITES DE DIALOGUE
4.4 BOITES DE SELECTION
4.5 L’APPLICATION GRAPHIQUE IMPOTS
4.6 ECRITURE D’APPLETS
4.7 L’APPLET IMPOTS
4.8 CONCLUSION
4.9 JBUILDER SOUS LINUX
5. GESTION DES BASES DE DONNEES AVEC L’API JDBC
5.1 GENERALITES
5.2 LES ETAPES IMPORTANTES DANS L’EXPLOITATION DES BASES DE DONNEES
5.3 IMPOTS AVEC UNE BASE DE DONNEES
5.4 EXERCICES
6. LES THREADS D’EXECUTION
6.1 INTRODUCTION
6.2 CREATION DE THREADS D’EXECUTION
6.3 INTERET DES THREADS
6.4 UNE HORLOGE GRAPHIQUE
6.5 APPLET HORLOGE
6.6 SYNCHRONISATION DE TACHES
7. PROGRAMMATION TCP-IP
7.1 GENERALITES
7.2 GESTION DES ADRESSES RESEAU EN JAVA
7.3 COMMUNICATIONS TCP-IP
7.4 APPLICATIONS
7.5 EXERCICES
8. JAVA RMI
8.1 INTRODUCTION
8.2 APPRENONS PAR L’EXEMPLE
8.3 DEUXIEME EXEMPLE : SERVEUR SQL SUR MACHINE WINDOWS
8.4 EXERCICES
9. CONSTRUCTION D’APPLICATIONS DISTRIBUEES CORBA
9.1 INTRODUCTION
9.2 PROCESSUS DE DEVELOPPEMENT D’UNE APPLICATION CORBA
9.3 EXEMPLE 2 : UN SERVEUR SQL
9.4 CORRESPONDANCES IDL – JAVA
……..