Introduction aux variables en Java

En Java, une variable est un conteneur qui contient des valeurs qui sont utilisées dans un programme Java. Chaque variable est assignée avec un type de données qui détermine quel type de valeurs elle peut contenir.

Déclaration de variables

Pour déclarer une variable en Java, vous devez spécifier le type et le nom de la variable. Par exemple :

int myNumber;

Dans cet exemple, int est le type de données (signifiant que cette variable peut contenir des nombres entiers) et myNumber est le nom de la variable.

Initialisation des variables

L’initialisation d’une variable signifie assigner une valeur à la variable lors de sa déclaration. Par exemple :

int myNumber = 5;

Dans cet exemple, la variable myNumber est initialisée avec la valeur 5.

Types de variables

Il existe trois types de variables en Java :

  1. Variables locales : Une variable définie à l’intérieur d’une méthode est appelée variable locale. Elle n’est accessible qu’à l’intérieur de cette méthode.
  2. Variables d’instance : Ce sont les variables déclarées à l’intérieur d’une classe mais en dehors d’une méthode. Ces variables sont créées lorsqu’un objet de la classe est créé.
  3. Variables de classe : Aussi appelées variables statiques, elles sont déclarées comme static, ce qui signifie qu’elles ne peuvent pas être locales. Il ne peut y avoir qu’une seule occurrence de telle variable par classe, indépendamment du nombre d’instances créées.

 

Variables en C++ vs Java

Déclaration de variables

C++ : En C++, une variable est déclarée de la manière suivante :

int myNumber;

Ici, int est le type de données et myNumber est le nom de la variable.

Java : En Java, la déclaration de variable est similaire à celle du C++. Par exemple :

int myNumber;

Initialisation des variables

C++ : En C++, vous pouvez initialiser une variable lors de sa déclaration :

int myNumber = 5;

Java : En Java, l’initialisation des variables est similaire à celle du C++. Par exemple :

int myNumber = 5;

 

Types de variables

 

En C++, il existe différents types de variables (définis avec différents mots-clés), tels que intdoublecharstring et bool. C++ permet également de définir divers autres types de variables, tels que Énumération, Pointeur, Tableau, Référence, Structures de données et Classes. 

En Java, il existe également différents types de variables, tels que les types primitifs (intdoubleboolean, etc.) et les types référence (classes, interfaces, tableaux).

Portée des variables
    1. C++: En C++, il existe six types de portées pour les variables: portée globale, portée de l’espace de noms, portée locale, portée de classe, portée d’instruction et portée de fonction. 
      • Portée globale : Un nom global est celui qui est déclaré en dehors de toute classe, fonction ou espace de noms.
      • Portée de l’espace de noms : Un nom qui est déclaré dans un espace de noms, en dehors de toute définition de classe ou d’énumération ou de bloc de fonction, est visible à partir de son point de déclaration jusqu’à la fin de l’espace de noms.
      • Portée locale : Un nom déclaré dans une fonction ou un lambda, y compris les noms des paramètres, a une portée locale.
      • Portée de classe : Les noms des membres d’une classe ont une portée de classe, qui s’étend sur toute la définition de la classe, quel que soit le point de déclaration.
      • Portée d’instruction : Les noms déclarés dans une instruction for, if, while ou switch sont visibles jusqu’à la fin du bloc d’instruction.
      • Portée de fonction : Une étiquette a une portée de fonction, ce qui signifie qu’elle est visible dans tout le corps d’une fonction, même avant son point de déclaration.
    2. En Java, il existe plusieurs portées pour les variables: portée de classe, portée de méthode, portée de boucle et portée de bloc.
      • Portée de classe : Les variables déclarées à l’intérieur des accolades d’une classe ({}), avec un modificateur d’accès privé, mais en dehors de toute méthode, ont une portée de classe. Par conséquent, ces variables peuvent être utilisées partout dans la classe, mais pas en dehors.
      • Portée de méthode : Lorsqu’une variable est déclarée à l’intérieur d’une méthode, elle a une portée de méthode et ne sera valide que dans la même méthode.
      • Portée de boucle : Si nous déclarons une variable à l’intérieur d’une boucle, elle aura une portée de boucle et ne sera disponible que dans la boucle.
      • Portée de bloc : Nous pouvons définir des portées supplémentaires n’importe où en utilisant des accolades ({}). La variable n’est valide que dans les accolades.
  1. Portée des variables: En Java, la portée des variables est généralement plus facile à comprendre et à gérer que celle en C++. En Java, chaque variable a une portée bien définie, c’est-à-dire un champ d’accessibilité dans lequel elle peut être utilisée1. En C++, il existe plusieurs types de portées pour les variables, ce qui peut rendre leur gestion plus complexe.
  2. Types de variables: En Java, il existe plusieurs types de variables prédéfinis, tels que les types primitifs (intdoubleboolean, etc.) et les types référence (classes, interfaces, tableaux)1. En C++, il existe également différents types de variables, mais la gestion des pointeurs et des références peut être plus complexe pour les débutants.
  3. Gestion de la mémoire: En Java, la gestion de la mémoire est automatique grâce au garbage collector1. En C++, la gestion de la mémoire doit être effectuée manuellement, ce qui peut rendre la gestion des variables plus complexe.
  4. Constantes: En C++, les variables constantes sont déclarées avec le mot-clé const. En Java, les variables constantes sont déclarées avec le mot-clé final.
  5. Conversion de type: En C++, toutes les conversions numériques de type par affectation sont acceptées quitte à dégrader fortement l’information. En Java, seules les conversions qui relèvent de promotion numérique sont autorisées par affectation (les autres doivent être demandées explicitement).
  6. Pointeurs: En C++, un pointeur représente l’adresse de l’objet pointé et on le manipule comme une variable. En Java, il n’existe pas de pointeur.

 

Types de variables en Java

En Java, il existe trois types de variables :

  1. Variables locales : Une variable définie à l’intérieur d’une méthode est appelée variable locale. Elle n’est accessible qu’à l’intérieur de cette méthode.
void myMethod() {
    int myVar = 0; // Ceci est une variable locale
}
  1. Variables d’instance : Ce sont les variables déclarées à l’intérieur d’une classe mais en dehors d’une méthode. Ces variables sont créées lorsqu’un objet de la classe est créé.
public class MyClass {
    int myVar; // Ceci est une variable d'instance
}
  1. Variables de classe : Aussi appelées variables statiques, elles sont déclarées comme static, ce qui signifie qu’elles ne peuvent pas être locales. Il ne peut y avoir qu’une seule occurrence de telle variable par classe, indépendamment du nombre d’instances créées.
public class MyClass {
    static int myVar; // Ceci est une variable de classe
}

Types de données en Java

En plus des types de variables, il est également important de comprendre les types de données en Java. Il existe deux catégories principales :

  1. Types primitifs : Ce sont les types de données les plus basiques disponibles en Java. Il existe huit types primitifs : byteshortintlongfloatdoublechar et boolean.

  2. Types référencés : Ce sont des types de données qui sont créés par le programmeur (comme les classes et les interfaces) ainsi que les types prédéfinis comme String.

 

Exemple:
 
// Ceci est une classe Java
public class MaClasse {

    // Ceci est une variable de classe (aussi appelée variable statique)
    static int maVariableStatique = 10;

    // Ceci est une variable d'instance
    int maVariableInstance = 20;

    public void maMethode() {
        // Ceci est une variable locale
        int maVariableLocale = 30;

        System.out.println("Variable statique : " + maVariableStatique);
        System.out.println("Variable d'instance : " + maVariableInstance);
        System.out.println("Variable locale : " + maVariableLocale);
    }

    public static void main(String[] args) {
        // Création d'un objet de la classe MaClasse
        MaClasse obj = new MaClasse();

        // Appel de la méthode maMethode sur l'objet obj
        obj.maMethode();
    }
}

Dans cet exemple, maVariableStatique est une variable de classe qui appartient à la classe MaClasse et non à une instance particulière de celle-ci. maVariableInstance est une variable d’instance, ce qui signifie qu’elle appartient à une instance particulière de la classe MaClasse. Enfin, maVariableLocale est une variable locale qui n’est accessible qu’à l’intérieur de la méthode maMethode.

 

Gestion de la mémoire

C++ : En C++, la gestion de la mémoire est manuelle. Le programmeur doit explicitement allouer et libérer la mémoire à l’aide des opérateurs new et delete.

Java : En Java, la gestion de la mémoire est automatique. Le ramasse-miettes (garbage collector) libère automatiquement la mémoire des objets qui ne sont plus utilisés.

 

Avantage de la gestion de la Mémoire Automatique en Java

 

La gestion automatique de la mémoire en Java, également connue sous le nom de ramasse-miettes (garbage collector), présente plusieurs avantages :

  1. Simplicité : Les développeurs n’ont pas besoin de se préoccuper explicitement de l’allocation et de la libération de la mémoire. Cela simplifie le code et réduit la charge mentale du développeur.

  2. Prévention des fuites de mémoire : En C++ et dans d’autres langages où la gestion de la mémoire est manuelle, il est courant d’oublier de libérer la mémoire, ce qui entraîne des fuites de mémoire. Le ramasse-miettes de Java évite ce problème en libérant automatiquement la mémoire des objets qui ne sont plus utilisés.

  3. Sécurité : La gestion automatique de la mémoire peut aider à prévenir certains types de bugs et de vulnérabilités liés à la mémoire, comme les débordements de tampon.

  4. Performance : Bien que le ramasse-miettes puisse parfois causer des retards dus à l’opération de nettoyage de la mémoire, les techniques modernes de ramasse-miettes sont très optimisées et peuvent souvent gérer la mémoire plus efficacement que le code écrit manuellement.

Cependant, il convient de noter que la gestion automatique de la mémoire a aussi ses inconvénients. Par exemple, elle peut parfois entraîner une utilisation imprévisible des ressources, ce qui peut être problématique pour les applications en temps réel ou à haute performance. De plus, elle peut masquer les bugs liés à la gestion incorrecte des ressources, qui ne se manifestent que lorsque le ramasse-miettes tente de nettoyer un objet.

 

Comment fonctionne le ramasse-miettes en Java?

Le ramasse-miettes (garbage collector) en Java est un processus qui gère automatiquement la mémoire en trouvant et en supprimant les objets qui ne sont plus utilisés par le programme, libérant ainsi de la mémoire. Voici comment cela fonctionne :

  1. Allocation d’objets : Lorsqu’un objet est alloué, la JVM vérifie la taille de l’objet. Elle distingue les petits et les grands objets. Les petits objets sont stockés dans une zone locale de thread (Thread Local Area - TLA) qui est un bloc libre du tas (heap). La TLA ne se synchronise pas avec d’autres threads. Lorsque la TLA est pleine, elle demande une nouvelle TLA. Les grands objets qui ne rentrent pas dans la TLA sont directement alloués dans le tas.

  2. Éligibilité à la collecte des déchets : Un objet devient éligible s’il n’est utilisé par aucun programme ou thread ou aucune référence statique ou si ses références sont nulles.

  3. Marquage et balayage : Le ramasse-miettes utilise un algorithme de marquage et de balayage pour marquer tous les objets inaccessibles comme étant à collecter, puis il parcourt les objets vivants pour trouver les objets qui sont encore accessibles.

  4. Libération de la mémoire : Lorsque le ramasse-miettes supprime un objet de la mémoire, il appelle d’abord la méthode finalize() de cet objet, puis le supprime.

Il est important de noter que bien que le ramasse-miettes en Java simplifie la gestion de la mémoire, il peut parfois entraîner une utilisation imprévisible des ressources, ce qui peut être problématique pour les applications en temps réel ou à haute performance.

 

 

Modifié le: jeudi 12 octobre 2023, 08:56