Les FAQs Java :
FAQ JAVA FAQ Java EE FAQ Java ME FAQ Java XML FAQ JavaFX FAQ Java GUI FAQ Struts FAQ JSF FAQ JDBC JDO FAQ Hibernate FAQ Spring FAQ Eclipse FAQ NetBeans FAQ JCreator FAQ Maven 2

FAQ JavaConsultez toutes les FAQ

Nombre d'auteurs : 53, nombre de questions : 231, dernière mise à jour : 26 janvier 2014 

 
OuvrirSommaireConcepts fondamentauxLes mots-clés

Un mot-clé est tout simplement un mot qui a été reservé pour une utilisation spéciale par le langage; vous ne pouvez donc pas employer des mots-clés comme noms de variable, ou nom de classe.

Pour avoir une liste de tous les mots-clés du langage Java et de leurs significations, vous pouvez lire cet article.

Mis à jour le 29 octobre 2008  par Baptiste Wicht

Ces trois mots clefs du langage java définissent la portée d'une variable, d'une méthode ou d'une classe. Il existe en fait quatre modificateurs d'accessibilité. Le quatrième est le modificateur vide (rien, pas de modificateur). Il ne faut pas confondre ce dernier avec public.

Voici les caractéristiques de ces modificateurs, du plus permissif au plus restrictif :

Mot-clé Portée Remarques
public Les variables, méthodes ou classes publiques sont accessibles par tout objet. Il ne peut y avoir qu'une seule classe publique par .java et celle-ci doit obligatoirement porter le nom du fichier .java
"rien" Les variables, méthodes ou classes définies sans modificateur sont accessibles par toute classe appartenant au même package. Attention : les variables sans modificateur ne sont pas accessibles aux classes fille définies dans un autre package.
protected Les variables, méthodes ou classes définies comme protégées ne sont accessibles que par les classes filles et classes du même package..  
private Les variables, méthodes ou classes définies comme privées ne sont accessibles que par la classe dans laquelle elles sont définies. Il est fortement conseillé de déclarer comme privés tous les attributs d'une classe, et de créer des méthodes de type get/set pour y accéder.

Naturellement, toute méthode, variable ou classe est accessible dans la classe ou elle est définie.

Remarque : il y a deux cas particuliers où l'abscence de mot-clé de visibilité ne correspond pas à une visibilité "package-only" :

  • Tous les membres (attributs et méthodes) d'une interface ou d'une annotation sont obligatoirement public.
  • Tous les constructeurs d'une enum sont obligatoirement private.
Mis à jour le 29 octobre 2008  par Ioan Calapodescu

Le mot-clé static est utilisable pour des variables, méthodes, classes internes ou blocs de code.

Devant une variable ou méthode :

Le mot clé static devant une variable (ou méthode) indique que celle-ci n'appartient pas à une instance particulière de la classe. Les variables ou méthodes statiques appartiennent à la classe elle-même. On peux ainsi les utiliser sans avoir une instance créée. De nombreuses classes ont des membres ou méthodes statiques. Par exemple la classe Math :

 
Sélectionnez

System.out.println(Math.PI);
//affiche la valeur de PI
System.out.println(Math.abs(-1));
//affiche la valeur absolue de -1

Voici quelques remarques :

  • On peut aussi manipuler une variable ou méthode statique à partir d'une instance de la classe.
  • Pour faire des variables statiques des constantes, il faut combiner le mot-clé static avec le mot-clé final.
  • Les méthodes statiques, étant indépendantes de toute instance, n'ont pas accès aux variables ou méthodes non statiques.

Devant un bloc de code :

Le mot-clé static devant un bloc de code indique que celui-ci ne sera exécuté qu'une fois. L'exécution se fait lors du chargement de la classe par le ClassLoader. On peut utiliser ces blocs, par exemple, pour initialiser des variables statiques complexes.

 
Sélectionnez

publioc class MaClasse{
   public static Map uneVariableStatique = new HashMap();
   static{
      uneVariableStatique.put("une clef","une valeur");
      uneVariableStatique.put("une autre clef","une autre valeur");
      //etc .
   }
}

Devant une classe interne :

Pour plus d'informations sur ce cas, reportez à la QR Quels sont les différents types de classes internes (nested classes) ?.

Mis à jour le 29 octobre 2008  par Ioan Calapodescu

Lien : Que signifie le mot-clé final ?

Devant une méthode :
On indique que cette méthode ne pourra plus être redéfinie dans une classe fille. Ce qui entraîne une certaine optimisation dans les appels à cette méthode.

Devant une classe :
On ne peut pas créer de classe dérivée de celle-ci. Par exemple il est impossible de dériver une classe à partir de la classe String de la bibliothèque de base. La solution consisterait à "encapsuler" String dans une classe de notre conception.

Devant une variable membre ou une variable locale :
La variable ne peut plus être modifiée après son initialisation, et doit obligatoirement être initialisée une fois (et une seule fois) :

Pour une variable membre, elle peut être initialisée :

en ligne à la déclaration :
Sélectionnez
private final int i = 5;
dans un bloc d'instance :
Sélectionnez
private final int i;
{
    i = 5;
}
ou dans le constructeur :
Sélectionnez
private final int i;
 
public Exemple() {
    i = 5;
}

Si la classe possède plusieurs constructeurs, la variable doit être correctement initialisée quel que soit le constructeur utilisé (sinon le compilateur provoquera une erreur).

Pour une variable membre static, elle peut être initialisée :

en ligne à la déclaration :
Sélectionnez
private static final int X = 5;
dans un bloc d'instance static :
Sélectionnez

private static final int X;
static {
    X = 5;
}

Devant un paramètre d'une méthode : empêche l'attribution d'une nouvelle valeur au paramètre:

 
Sélectionnez
public void methode(final List<Object> liste, final int entier){
  entrier = 0; // interdit
  liste = new ArrayList<Object>(); // interdit
}

Pour une variable locale (ou pour un paramètre de la méthode), cela permet également de référencer l'instance dans une classe anonyme.

Mis à jour le 20 décembre 2009  par Clément Cunin

Les mots-clés this et super désignent respectivement des références sur l'instance courante et sur la classe mère. Voici un exemple qui devrais mettre en valeur cette définition plutôt succincte :

 
Sélectionnez

public MaClasse extends ClasseMere {
   private String attribut;
   /** On peut acceder aux constructeurs de la super-classe*/
   public MaClasse(String uneValeur){
      super(uneValeur);
      //on appelle ici le constructeur de la classe mère
   }
   /** On peut aussi accéder aux constructeurs de la classe elle-même*/
   public MaClasse(String uneValeur){
      this("une valeur par défaut");
      //on appelle ici le constructeur définis un peu plus haut
   }
   /** En général l'appel à this est superflu lors d'appels à une méthode*/
   public void uneMethode(){}
   public void doubleAppel(){
      //les deux lignes suivantes sont équivalentes
      this.uneMethode();
      uneMethode();
   }
   /** L'appel à this peut être utile pour bien différencier
      * les variables de classe des variables de méthodes
      */
   public void uneMethode(String attribut){
      this.attribut = attribut;
      //ici, la variable de classe prend la valeur de la variable
      //passée en paramètre de la méthode
   }
   /** On peut aussi faire appel aux méthodes de la super-classe*/
   public void uneAutreMethode(){
      //on peux faire quelque chose en plus avant
      super.uneAutreMethode();
      //mais aussi après
   }
}

A noter que dans le cas d'une classe interne (non static), le mot clé this permet également de récupérer l'instance de la classe englobante :

 
Sélectionnez

public class Englobante {
	private Object attribut;
 
	public final class Interne {
		private Object attribut;
 
        private switch() {
			Englobante.this.attribut = this.attribut;
        }
    }
}

Englobante.this fait donc référence à l'instance de la classe englobante et this fait référence à la classe interne.

Ces deux mots-clés sont très liés au concept d'héritage. Pour plus d'informations, voir Qu'est-ce que l'héritage ?

Mis à jour le 20 décembre 2009  par Ioan Calapodescu, tchize

Lien : Qu'est-ce que l'héritage ?

Ce mot clé, qui est une abréviation de Strict floating point, s'applique en tant que modificateur d'accès. Ou plus simplement, on l'utilise de la même manière que les mot-clés public ou synchronized. Avec quelques restrictions : strictfp s'applique en tant que modificateurs de classes, d'interfaces ou de méthodes d'une classe et en aucun cas au constructeur ou aux méthodes d'une interface. L'entité affectée est alors dite "FP-strict".

Les effets :
Comme son nom l'indique, strictfp agit sur les opérations en virgule flottante. C'est à dire sur les types primitifs double et float.

Java effectue les calculs en garantissant une priorité de la gauche vers la droite.

 
Sélectionnez

/** classe FP-strict */
public strictfp class FPDemo {
        public static void main(String[] args) {
                double d = 8e+307;
                /** affiche 4 * d /2 donc 2 * d */
                System.out.println(4 * d / 2);
                /** affiche 2 * d */
                System.out.println(2 * d);
        } 
} 

Mathématiquement ces deux expressions sont identiques, mais interprétées dans un langage, il en va autrement. Java impose un parenthésage : (4*d)/2, et dans notre cas (4*d) produit un dépassement de capacité, donc un résultat infini. En revanche, la deuxième expression produit bien un résultat correct.

Notons que le mot-clé oblige l'implémentation de la JVM à évaluer l'expression tel que prévu dans la spécification du langage. Ne pas faire usage de ce mot-clé ne garantit pas que la JVM réalisera ce calcul de la sorte. Une JVM peut en effet avoir le droit, si la méthode n'est pas FP-strict, d'utiliser des types intermédiaires différents pour éviter de provoquer un dépassement de capacité ou pour s'adapter à l'architecture de la machine. Dans ce cas les deux expressions pourraient, en fonction de la JVM, produire des résultats différents.

Conclusion :
Le mot-clé strictfp permet de garantir les mêmes calculs quelle que soit la machine virtuelle sur laquelle l'opération est effectuée.

Mis à jour le 29 octobre 2008  par Romain Guy, Clément Cunin

Le mot-clé transient est lié à la sérialisation des classes Java (voir : Qu'est-ce que la sérialisation ?). Il permet d'interdire la sérialisation de certaines variables d'une classe.

 
Sélectionnez

// la classe que nous allons sérialiser
class Writeable implements java.io.Serializable {
        // entier transient
        public transient int var1 = 4;
        // entier normal
        public int var2 = 19;
} 

Si nous sérialisons une instance de cette classe, la variable 'var1' ne sera pas sauvegardée, lors de la désérialisation elle prendra la valeur 0, malgré la présence de la valeur par défaut 4. L'attribution d'une valeur par défaut se fait lors de l'instanciation de l'objet ! Or, la méthode consistant à lire un objet depuis un fichier ne crée pas cette instance explicitement. Donc demo n'est jamais initialisé avec sa valeur par défaut. De plus, comme cet attribut est transient, il n'est pas écrit dans le fichier. Cela implique que demo ne reçoit aucune valeur et contient donc 0.

Ce mot-clé trouve des applications dès lors qu'une donnée sensible ne doit en aucun cas apparaître dans un fichier. Un mot de passe par exemple. Mais ce mot-clé peut également permettre de "remettre à zéro" certaines valeurs. Dans le cas d'un jeu, on pourra ainsi ne pas sauvegarder le temps de jeu depuis le début de la partie.

Créé le 27 janvier 2003  par Romain Guy

Lien : Qu'est-ce que la sérialisation ?

Le mot-clé volatile est utilisé sur les variables qui peuvent être modifiées de manière asynchrone. C'est à dire que plusieurs threads peuvent y accéder simultanément. Ces accès peuvent être pour la lecture et/ou la modification du contenu.

En indiquant que la variable est volatile, on oblige la JVM à rafraîchir son contenu à chaque fois qu'elle est utilisée. On est ainsi certain que la valeur de la variable n'est pas une valeur mise en cache, mais bel et bien sa valeur exacte. Ainsi chaque thread a accès à la valeur la plus récente de la variable.

Remarque : ce mot-clé est relativement peu utilisé et toutes les JVM ne le prennent pas en compte.

Mis à jour le 29 octobre 2008  par Ioan Calapodescu

goto
Bien que goto soit un mot réservé de Java, on ne le trouve pas dans le langage ; Java n'a pas de goto. Le mot-clé goto est aussi ancien que les langages de programmation. En effet, goto a été le premier moyen de contrôle des programmes dans les langages d'assemblage : « si la condition A est satisfaite, alors sauter ici, sinon sauter là ». Lorsqu'on lit le code assembleur finalement généré par n'importe quel compilateur, on voit qu'il comporte beaucoup de sauts.

break & continue
Cependant, il existe quelque chose qui ressemble à un saut, lié aux mots-clés break et continue. Ce n'est pas vraiment un saut, mais plutôt une manière de sortir d'une instruction d'itération.

 
Sélectionnez

while(true) {
        // instructions
 
        if( condition ) {
                 // quitte la boucle 
                break;
        } 
        if( condition ) {
                // retourne au début de la boucle 
                continue; 
       } 
} 

Pour plus d'informations sur break et continue, regardez le lien ci dessous.

Créé le 31 mai 2002  par Clément Cunin

Lien : Comment utiliser les mots-clés break et continue ?

Comme nous l'avons vu, il n'y a pas de goto en Java, mais il est possible d'associer un label à une instruction de boucle. Ce label, utilisé en conjonction avec l'instruction break, permet de savoir à quel niveau le break sera effectif.

Un label est une chaîne suivie de ":" et qui se place devant l'instruction de boucle.

Voici un exemple :

 
Sélectionnez
Boucle1: while(true){ 
	System.out.println("Boucle 1"); 
 
	Boucle2: for(int ind=0; ind < 10; ind++) { 
		System.out.println("Boucle 2"); 
 
		Boucle3: while(true){ 
			System.out.println("Boucle 3"); 
			break Boucle2; 
		} 
	} 
 
	break; 
} 
 

A votre avis, qu'affiche l'exécution de ce morceau de code ?

Remarque : le label peut aussi être utilisé en conjonction avec le mot clé continue. De la même manière, le label indique à quel niveau de boucle le continue s'applique.

Mis à jour le 29 octobre 2008  par bulbo

L'instruction switch n'accepte que les types de base, c'est à dire:

  • byte
  • char
  • short
  • int
  • long
  • float
  • double

Il n'est pas possible de faire un switch sur une String par exemple. Il faudra passer par une séquence de if .. else if:

 
Sélectionnez

if ("A".equals(maString))
{
  // ...
}
else if ("B".equals(maString))
{
  // ...
}

Il est possible aussi que le compilateur reporte cette erreur:

case expressions must be constant expressions

En effet l'instruction case n'accepte que des constantes.

Des constantes explicites comme dans ce cas:

 
Sélectionnez

case 1:
...
break;

Ou une variable déclarée comme constante à l'aide du mot-clé final.

Ainsi si vous obtenez une erreur avec le code suivant:

 
Sélectionnez

int a = 1;
 
switch (maVar)
{
  case a:
  ...
}

Vous ne l'aurez plus avec celui-ci:

 
Sélectionnez

final int a = 1;
 
switch (maVar)
{
  case a:
}
Créé le 12 octobre 2006  par bulbo

L'ellipse permet de créer des méthodes (ou des constructeurs) avec un nombre d'arguments variable. On utilise pour cela trois points (...) après le type des arguments, par exemple la méthode suivante accepte un nombre quelconque de String :

Méthode avec un nombre d'argument variable :
Sélectionnez

public void method (String... args) {
   // 
}

A l'intérieur de la méthode, le paramètre args est un tableau contenant les différents paramètres passés à la méthode. Ainsi, cette méthode peut s'utiliser de la manière suivante :

Exemple d'utilisation :
Sélectionnez

// avec 1 paramètre :
method ("param1");
 
// avec plusieurs paramètres :
method ("param1", "param2", "param3");
 
// sans paramètres :
method ();

En réalité, il ne s'agit ni plus ni moins qu'une nouvelle manière de déclarer une méthode avec un tableau en paramètre. En effet, pour le compilateur, cette déclaration correspond à la déclaration d'une méthode avec un tableau de String en paramètre. Et lors de son utilisation, les différents paramètres de l'ellipse sont automatiquement stockés dans un tableau. Ainsi, les exemples d'utilisations ci-dessus correspondent en réalité au code suivant :

 
Sélectionnez

// avec 1 paramètre :
method ( new String[]{"param1"} );
 
// avec plusieurs paramètres :
method ( new String[]{"param1", "param2", "param3"} );
 
// sans paramètres :
method ( new String[]{} );

On ne peut toutefois utiliser qu'un seul type d'argument variable par méthode, et il doit obligatoirement être en dernière position dans la liste des paramètres.

Créé le 22 août 2005  par adiGuba

Lien : Présentation de Tiger : l'ellipse

Le nouveau for de Java 5.0 permet de parcourir tous les éléments d'un élément 'itérable' sans se soucier de son fonctionnement. Il se présente de la forme suivante :

La boucle for étendu :
Sélectionnez

for ( Type variable : Iterable ) {
   // ...
}
  • Type correspond au type de l'élément de la variable qui contiendra les différentes valeurs.
  • variable est justement le nom de cette variable à l'intérieur de la boucle.
  • Iterable est l'élément dont les valeurs seront parcourues. Ce doit obligatoirement être soit un tableau, soit une classe implémentant l'interface Iterable.

L'interface Iterable décrit une unique méthode iterator() retournant un Iterator qui sera utilisé par la boucle for pour parcourir les différents éléments. Les Collections de Java implémentent bien entendu cette interface. De plus, le type de la variable doit correspondre au type paramétré de l'Iterator, ce qui permet de se passer de cast et d'utiliser un code sécurisé :

Parcours d'une liste paramétrée
Sélectionnez

List<String> list = new ArrayList<String>();
 
list.add("chaine1");
list.add("chaine2");
list.add("chaine3");
list.add("chaine4");
 
// Affichage des éléments en MAJUSCULE :
for (String s : list) {
   System.out.println(s.toUpperCase());
}

Si la boucle est utilisée avec un tableau, le type de la variable doit correspondre avec le type du tableau. Si elle est utilisée avec un objet implémentant l'interface Iterable, le type de la variable doit correspondre au type paramétré d'Iterable (par exemple,* List<String> implémente Iterable<String> et permet donc d'utiliser une String dans la boucle).

Et du fait de son fonctionnement, il est possible de l'utiliser avec n'importe quel type de classe du moment que cette dernière implémente correctement l'interface Iterable<T> (T étant le type à utiliser dans la boucle for...

Créé le 22 août 2005  par adiGuba

Lien : Présentation de Tiger : la nouvelle boucle for
Lien : java.lang.Iterable

Le code suivant parcourt un tableau à 2 dimensions d'entiers et les affiche.

 
Sélectionnez

int tab[][] = { {1, 2, 3}, {7, 8, 9} };
 
for(int ligne[] : tab)
{
  for(int element : ligne)
  {
    System.out.println("Item : " + element);
  }
}
Créé le 12 octobre 2006  par bulbo

L'import static permet d'importer les éléments statiques d'une classe afin d'alléger l'écriture du code. Cela permet en effet de ne pas préfixer les éléments statiques par le nom de la classe. Par exemple, les deux codes suivant sont identiques mis à part que le second utilise un import static pour accéder aux méthodes de la classe Math :

Utilisation normale des méthodes statiques :
Sélectionnez

public Class Test {
   public void calcul (int i) {
      Math.round(Math.cos(i*(Math.PI/6)-Math.PI/2)*Math.E);
   }
}
Utilisation d'un import static :
Sélectionnez

import static java.lang.Math.*;
 
public Class Test {
   public void calcul (int i) {
      round(cos(i*(PI/6)-PI/2)*E);
   }
}

Ce mécanisme est proche du mot-clef using namespace du C++. Toutefois, il est conseillé de limiter son utilisation afin de faciliter la lecture du code et éviter des conflits potentiels. On peut pour cela importer seulement l'élément qui nous intéresse, par exemple :

Importation de System.out seulement :
Sélectionnez

import static java.lang.System.out;
 
public Class Test {
   public void print () {
      out.println("Message d'information");
      System.err.println("Message d'erreur");
   }
}
Créé le 22 août 2005  par adiGuba

Le import et le import static n'ont pas la même fonction.

Le import se fait sur une classe (ou un ensemble de classes via le *) et permet d'éviter de spécifier le package de la classe à chaque fois qu'on l'utilise (en partant du principe que l'on se trouve dans un paquage différent de celui contenant la classe).

Le import static a un fonctionnement similaire mais pour les méthodes et les attributs statiques d'une classe ou d'une interface et les membres d'une enum. En effet, il permet d'éviter de spécifier la classe de la méthode ou de l'attribut statique à chaque fois qu'on l'utilise (en partant du principe que l'on se trouve dans une classe différente de celle contenant la méthode ou l'attribut).

Illustration :

Soit les classes package_a.ClasseA et package_b.ClasseB.

Pour "utiliser" la classe ClasseA dans la classe ClasseB il faut normalement spécifier le package comme suit :

 
Sélectionnez

package package_b;
 
public class ClasseB {
    private package_a.ClasseA a;
 
    public CLasseB() {
        a = new package_a.ClasseA();
    }
}

Le import permet de supprimer cet inconvénient en indiquant à l'avance dans quel package se situe la classe ClasseA et permet donc d'écrire

 
Sélectionnez

package package_b;
 
import package_a.ClasseA;
 
public class ClasseB {
    private ClasseA a;
 
    public CLasseB() {
        a = new ClasseA();
    }
}

On se retrouve avec la même écriture que si la classe ClasseA était dans le même package que la classe ClasseB.

Supposont maintenant que la classe ClasseA posséde la méthode statique suivante :

 
Sélectionnez

public static void staticMethod() {
    // code
}

Pour l'appeler depuis la classe ClasseB il faut normalement écrire

 
Sélectionnez

ClasseA.staticMethod();

En faisant un import static de la méthode on se retrouve comme si la méthode statique faisait partie de la classe ClasseB et nous permet d'écrire

 
Sélectionnez

import static package_a.ClasseA.staticMethod;
 
...
 
staticMethod();

Ces deux imports sont indépendants, si je ne fait que le import je pourrait écrire

 
Sélectionnez

ClasseA

mais je devrais écrire

 
Sélectionnez

ClasseA.staticMethod();

A l'inverse je pourrais très bien ne faire que l'import static et je me retrouverais à devoir écrire

 
Sélectionnez

package_a.ClasseA

mais à pouvoir écrire directement

 
Sélectionnez

staticMethod();

En résumé il est important de bien retenir que

  • le import ne permet la simplification d'écriture que pour les classes
  • le import static ne permet la simplification d'écriture que pour les méthodes et les attributs statiques d'une classe ou interface et les membres d'une enum
  • le import et le import static sont indépendants
Mis à jour le 29 octobre 2008  par le y@m's

Lien : [Java 5.0] Qu'est-ce que l'import static ?


On le considère souvent comme une syntaxte réduite de l'instruction if traditionnelle.

Mais c'est avant tout un opérateur au sens où il produit une valeur.

 
Sélectionnez

(A) ? B : C


Si A alors le résultat est B sinon c'est C.

A noter que B est évalué seulement si A et que C est évalué seulement si non A.


Il fournit un moyen compact d'écrire une affectation conditionnée:

 
Sélectionnez

chaine=(nouvelleChaine!=null) ? nouvelleChaine : "";


à la place de:

 
Sélectionnez

if (nouvelleChaine!=null) {chaine=nouvelleChaine;} else {chaine="";}


NB: Utilisé abusivement il devient rapidement illisible.

Créé le 25 août 2007  par JMLLB
Les codes sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Pour le reste, ce document constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Ce document issu de http://www.developpez.com est soumis à deux licences, en fonction des contributeurs : - Les contributions de Clément Cunin et Johann Heymes sont soumises aux termes de la la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies des contributions de Clément Cunin et Johann Heymes tant que cette note apparaît clairement : "Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement". - Pour ce qui est des autres contributions : Copyright © 2014 Developpez LLC : Tous droits réservés Developpez LLC. Aucune reproduction, ne peut en être faite sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.