CodeGym/Blog Java/Random-FR/Valeurs fixes en Java : finales, constantes et immuables
Auteur
Aditi Nawghare
Software Engineer at Siemens

Valeurs fixes en Java : finales, constantes et immuables

Publié dans le groupe Random-FR
membres
Salut! Vous connaissez déjà le mot "modificateur". Au minimum, vous avez rencontré des modificateurs d'accès (public, privé) et le modificateur statique. Aujourd'hui, nous allons discuter d'un modificateur spécial appelé final . Vous pourriez dire que le modificateur final "cimente" les parties de notre programme où des comportements constants, sans ambiguïté et immuables sont nécessaires. Il y a trois endroits dans vos programmes où vous pouvez l'utiliser : les classes, les méthodes et les variables. Valeurs fixes en Java : finales, constantes et immuables - 2 Parcourons-les dans l'ordre. Si le modificateur final est utilisé dans une déclaration de classe, cela signifie que la classe ne peut pas être héritée. Dans les leçons précédentes, nous avons utilisé un exemple d'héritage simple : nous avions une Animalclasse parent et deux classes enfants : CatetDog
public class Animal {
}



public class Cat extends Animal {
   // Fields and methods of the Cat class
}


public class Dog extends Animal {

   // Fields and methods of the Dog class
}
Cependant, si nous utilisons le modificateur final sur la Animalclasse, les classes Catet Dogne peuvent pas en hériter.
public final class Animal {

}

public class Cat extends Animal {

   // Error! Cannot inherit from final Animal
}
Le compilateur génère immédiatement une erreur. En Java, de nombreuses classes finales sont déjà implémentées. Parmi ceux que vous utilisez fréquemment, Stringest le plus connu. De plus, si une classe est déclarée comme final , toutes les méthodes de la classe deviennent également final . Qu'est-ce que cela signifie? Si une méthode est déclarée à l'aide du modificateur final , vous ne pouvez pas remplacer cette méthode. Par exemple, nous avons ici une Animalclasse qui déclare une speak()méthode. Mais, les chiens et les chats "parlent" définitivement de différentes manières. Nous allons donc déclarer les méthodes speak() dans les classes Catet Dog, mais nous les implémenterons différemment.
public class Animal {

   public void speak() {
       System.out.println("Hello!");
   }
}

public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void speak() {
       System.out.println("Woof!");
   }
}
Nous avons fait en sorte que les classes Catet Dogremplacent la méthode déclarée dans la classe parent. Or, un animal parlera différemment selon le type d'objet dont il s'agit :
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       Dog dog = new Dog();

       cat.speak();
       dog.speak();
   }
}
Sortie : Miaou ! Trame! Cependant, si nous déclarons la méthode Animalde la classe speak()comme final, nous ne pouvons pas la remplacer dans d'autres classes :
public class Animal {

   public final void speak() {
       System.out.println("Hello!");
   }
}


public class Cat extends Animal {

   @Override
   public void speak() {// Error! A final method can't be overridden!
       System.out.println("Meow!");
   }
}
Et nos objets seront forcés d'utiliser la speak()méthode telle que définie dans la classe parent :
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   cat.speak();
   dog.speak();
}
Sortie : Bonjour ! Bonjour! Maintenant, concernant les variables finales . Elles sont également appelées constantes . Tout d'abord (et surtout), la valeur initiale affectée à une valeur constante ne peut pas être modifiée. Il est attribué une fois pour toutes.
public class Main {

   private static final int CONSTANT_EXAMPLE = 333;

   public static void main(String[] args) {

       CONSTANT_EXAMPLE = 999;// Error! You can't assign a new value to a final variable!
   }
}
Une constante n'a pas besoin d'être initialisée immédiatement. Cela peut être fait plus tard. Mais, la valeur qui lui est initialement attribuée restera la même pour toujours.
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;// This is allowed
}
Deuxièmement, notez le nom de notre variable. Java a une convention de nommage différente pour les constantes. Ce n'est pas la notation camelCase habituelle . S'il s'agissait d'une variable ordinaire, nous l'aurions appelée constanteExemple. Mais, les noms des constantes sont écrits en majuscules, avec des traits de soulignement entre les mots (s'il y a plus d'un mot), par exemple "CONSTANT_EXAMPLE". Pourquoi avons-nous besoin de constantes ? Ils sont très utiles si, par exemple, il existe une valeur fixe que vous utilisez régulièrement dans un programme. Par exemple, vous avez décidé d'entrer dans l'histoire et d'écrire vous-même le jeu "The Witcher 4". Le jeu utilisera bien évidemment régulièrement le nom du protagoniste : "Geralt of Rivia". Cette chaîne (et les noms d'autres héros) est mieux déclarée comme une constante : sa valeur sera stockée à un seul endroit, et vous ne ferez certainement pas de faute de frappe en la saisissant un million de fois.
public class TheWitcher4 {

   private static final String GERALT_NAME = "Geralt of Rivia";
   private static final String YENNEFER_NAME = "Yennefer of Wengerberg";
   private static final String TRISS_NAME = "Triss Merigold";

   public static void main(String[] args) {

       System.out.println("The Witcher 4");
       System.out.println("It's already the fourth Witcher game, but " + GERALT_NAME + " still can't decide who" +
               " he likes more: " + YENNEFER_NAME + " or " + TRISS_NAME);

       System.out.println("But, if you've never played The Witcher before, we'll start from the beginning.");
       System.out.println("The protagonist's name is " + GERALT_NAME);
       System.out.println(GERALT_NAME + " is a witcher, a monster hunter");
   }
}
Sortie : The Witcher 4 C'est déjà le quatrième jeu Witcher, mais Geralt de Riv n'arrive toujours pas à décider qui il aime le plus : Yennefer de Wengerberg ou Triss Merigold Mais, si vous n'avez jamais joué à The Witcher auparavant, nous commencerons par le début. Le nom du protagoniste est Geralt de Riv Geralt de Riv est un sorceleur, un chasseur de monstres Nous avons déclaré les noms des héros comme des constantes. Maintenant, nous ne ferons certainement pas de faute de frappe, et il n'est pas nécessaire de les écrire à la main à chaque fois. Autre avantage : si nous avons besoin de modifier la valeur de la variable dans l'ensemble du programme, vous pouvez le faire à un seul endroit, plutôt que de la modifier manuellement dans l'ensemble de la base de code. :)

Types immuables

Comme vous avez travaillé avec Java, vous vous êtes probablement déjà habitué à l'idée que les programmeurs ont un contrôle presque total sur l'état de tous les objets. Si vous voulez créer un Catobjet, vous le pouvez. Si vous voulez le renommer, vous le pouvez. Si vous voulez changer son âge ou autre chose, vous le pouvez. Mais Java a plusieurs types de données qui ont une propriété spéciale. Ils sont immuables . Si une classe est immuable, l'état de ses objets ne peut pas être modifié. Vous voulez des exemples ? Cela pourrait vous surprendre, mais la classe immuable la plus connue est String ! Donc, nous ne pouvons vraiment pas changer la valeur d'une chaîne ? Eh bien, essayons:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1 = "I love Python";// but changing str1 has no impact on str2
   System.out.println(str2);// str2 continues to point to the "I love Java" string, but str1 now points to a different object
}
Sortie : J'aime Java J'aime Java Après avoir écrit
str1 = "I love Python";
l' "I love Java"objet chaîne n'a pas changé ou n'est allé nulle part. Il existe toujours heureusement et a exactement le même texte qu'avant. Le code
str1 = "I love Python";
a simplement créé un autre objet, vers lequel str1 pointe maintenant. Mais, nous ne pouvons sembler avoir aucun effet sur l'objet de chaîne "J'aime Java". Bon, essayons autre chose ! La Stringclasse est pleine de méthodes, et certaines d'entre elles semblent changer l'état de l'objet ! Par exemple, il y a une replace()méthode. Remplaçons le mot "Java" par "Python" dans notre chaîne !
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1.replace("Java", "Python");// We try to change the state of str1 by swapping the word "Java" with "Python"
   System.out.println(str2);
}
Résultat : J'adore Java J'adore Java Cela n'a plus fonctionné ! Peut-être que la méthode de remplacement ne fonctionne pas ? Essayons autre chose. Par exemple, substring(). Il renvoie une sous-chaîne basée sur des indices de caractères passés en arguments. Coupons les 10 premiers caractères de notre chaîne :
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1.substring(10);// Truncate the original String
   System.out.println(str2);
}
Résultat : J'adore Java J'adore Java Valeurs fixes en Java : finales, constantes et immuables - 3 Rien n'a changé. Et ça n'aurait pas dû. Comme nous l'avons dit précédemment, les chaînes sont immuables. Alors, qu'en est-il de toutes les méthodes de la Stringclasse ? Après tout, ils peuvent tronquer des chaînes, modifier des caractères, etc. A quoi bon si rien ne se passe ? Ils peuvent réellement faire ces choses ! Mais, ils renvoient une nouvelle chaîne à chaque fois. C'est inutile d'écrire
str1.replace("Java", "Python");
car vous ne pouvez pas modifier l'objet d'origine. Mais, si vous écrivez le résultat de la méthode dans une nouvelle variable de référence, vous verrez immédiatement la différence !
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   String str1AfterReplacement =  str1.replace("Java", "Python");
   System.out.println(str2);

   System.out.println(str1AfterReplacement);
}
Toutes Stringles méthodes fonctionnent ainsi. Rien ne peut être fait sur l' "I love Java"objet. Vous pouvez simplement créer un nouvel objet et écrire : "<nouvel objet> = le résultat de la manipulation du "I love Java" object ". Quels autres types sont immuables ? Certains dont vous devrez certainement vous souvenir immédiatement sont toutes les classes wrapper pour les types primitifs. Integer, Byte, Character, Short, Boolean, Long, Double,Float : toutes ces classes créent immutabledes objets (nous en parlerons dans les leçons à venir). Cela inclut les classes utilisées pour créer de grands nombres, comme BigIntegeret BigDecimal. Nous avons récemment couvert les exceptions et abordé la trace de la pile . Eh bien , devinez quoi, java.lang.StackTraceElementles objets sont également immuables. Cela a du sens : si quelqu'un pouvait modifier les données de notre pile, cela rendrait le tout inutile. Imaginez que quelqu'un passe par la trace de la pile et remplace une OutOfMemoryError par une FileNotFoundException . Et puis vous utilisez cette pile pour trouver la cause de l'erreur. Mais le programme n'utilise même pas de fichiers. :) Donc, ils ont rendu ces objets immuables, juste au cas où. D'accord, donc cela a plus ou moins de sens pour StackTraceElement . Mais pourquoi aurait-on besoin de rendre Strings immuable ? Pourquoi changer leurs valeurs serait-il un problème ? Ce serait sans doute même plus pratique. :/ Il y a plusieurs raisons à cela. Tout d'abord, il économise de la mémoire. Des chaînes immuables peuvent être placées dans le pool de chaînes, permettant aux chaînes d'être réutilisées au lieu d'en créer de nouvelles. Deuxièmement, pour la sécurité. Par exemple, les noms d'utilisateur et les mots de passe sont des chaînes dans presque tous les programmes. Rendre possible leur modification pourrait entraîner des problèmes d'autorisation. Il existe d'autres raisons, mais notre étude de Java ne les a pas encore couvertes, nous y reviendrons plus tard.
Commentaires
  • Populaires
  • Nouveau
  • Anciennes
Tu dois être connecté(e) pour laisser un commentaire
Cette page ne comporte pas encore de commentaires