JavaRush /Blog Java /Random-FR /Final, constantes et immuables en Java

Final, constantes et immuables en Java

Publié dans le groupe Random-FR
Bonjour! Le mot « modificateur » vous est déjà familier. Au minimum, vous avez rencontré des modificateurs d'accès (public, privé) et le modificateur statique. Aujourd'hui, nous allons parler du modificateur final spécial . On peut dire qu’elle « cimente » les domaines de notre programme où nous avons besoin d’un comportement constant, sans ambiguïté et immuable. Il peut être utilisé dans trois domaines de notre programme : les classes, les méthodes et les variables. Immuable en Java : final, constantes et Immuable - 2 Passons-les un par un. Si une déclaration de classe contient le modificateur final , cela signifie que vous ne pouvez pas hériter de cette classe. Dans les cours précédents, nous avons vu un exemple simple d'héritage : nous avions une classe parent Animalet deux classes enfants - CatetDog
public class Animal {
}

public class Cat extends Animal {
   //..поля и методы класса Cat
}

public class Dog extends Animal {

   //..поля и методы класса Dog
}
Cependant, si nous spécifions Animalun modificateur pour une classe final, les classes ne pourront pas Catnon plus en hériter Dog.
public final class Animal {

}

public class Cat extends Animal {

   //ошибка! Cannot inherit from final Animal
}
Le compilateur produit immédiatement une erreur. Il existe de nombreuses classes déjà implémentées en Java final. Le plus connu de ceux que vous utilisez constamment est String. De plus, si une classe est déclarée comme final, toutes ses méthodes deviennent également final. Qu'est-ce que ça veut dire? Si un modificateur est spécifié pour une méthode final, cette méthode ne peut pas être remplacée. Par exemple, nous avons une classe Animalqui définit une méthode voice(). Cependant, les chiens et les chats « parlent » clairement différemment. Par conséquent, dans chacune des classes - Catet Dog- nous créerons une méthode voice(), mais nous l'implémenterons différemment.
public class Animal {

   public void voice() {
       System.out.println("Voice!");
   }
}

public class Cat extends Animal {

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

public class Dog extends Animal {

   @Override
   public void voice() {
       System.out.println("Woof!");
   }
}
Dans les classes Catet Dognous avons remplacé la méthode de la classe parent. Maintenant, l'animal vocalisera en fonction de l'objet de classe dont il s'agit :
public class Main {

   public static void main(String[] args) {

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

       cat.voice();
       dog.voice();
   }
}
Conclusion : Miaou ! Trame! Cependant, si Animall'on déclare une méthode dans une classe voice()comme final, il ne sera pas possible de la redéfinir dans d'autres classes :
public class Animal {

   public final void voice() {
       System.out.println("Voice!");
   }
}


public class Cat extends Animal {

   @Override
   public void voice() {//ошибка! final-метод не может быть переопределен!
       System.out.println("Meow!");
   }
}
Ensuite nos objets seront obligés d'utiliser la méthode voice()telle qu'elle est définie dans la classe parent :
public static void main(String[] args) {

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

   cat.voice();
   dog.voice();
}
Conclusion : Voix ! Voix! Parlons maintenant finaldes -variables. Sinon, elles sont appelées constantes . Premièrement (et surtout), la première valeur attribuée à une 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;//ошибка! Нельзя присвоить новое meaning final-переменной!
   }
}
La constante n'a pas besoin d'être initialisée immédiatement. Cela peut être fait plus tard. Mais la valeur attribuée en premier restera pour toujours.
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;//так делать можно
}
Deuxièmement, faites attention au nom de notre variable. Les constantes Java ont une convention de dénomination différente. Ce n’est pas le camelCase auquel nous sommes habitués. Dans le cas d'une variable régulière, nous l'appellerions constantExample, mais les noms des constantes sont écrits en majuscules, et entre les mots (s'il y en a plusieurs) il y a un trait de soulignement - « CONSTANT_EXAMPLE ». Pourquoi des constantes sont-elles nécessaires ? Par exemple, ils seront utiles si vous utilisez constamment une valeur constante dans un programme. Disons que vous décidez d'entrer dans l'histoire et d'écrire seul le jeu « The Witcher 4 ». Le jeu utilisera évidemment constamment le nom du personnage principal – « Geralt de Riv ». Il est préférable de séparer cette ligne et les noms des autres héros en une constante : la valeur dont vous avez besoin sera stockée au même endroit, et vous ne ferez certainement pas d'erreur en la tapant pour la millionième fois.
public class TheWitcher4 {

   private static final String GERALT_NAME = "Геральт из Ривии";
   private static final String YENNEFER_NAME = "Йеннифэр из Венгерберга";
   private static final String TRISS_NAME = "Трисс Меригольд";

   public static void main(String[] args) {

       System.out.println("Ведьмак 4");
       System.out.println("Это уже четвертая часть Ведьмака, а " + GERALT_NAME + " ниHow не определится кто ему" +
               " нравится больше: " + YENNEFER_NAME + " or " + TRISS_NAME);

       System.out.println("Но если вы никогда не играли в Ведьмака - начнем сначала.");
       System.out.println("Главного героя зовут " + GERALT_NAME);
       System.out.println(GERALT_NAME + " - ведьмак, охотник на чудовищ");
   }
}
Conclusion:
Ведьмак 4
Это уже четвертая часть Ведьмака, а Геральт из Ривии ниHow не определится, кто ему нравится больше: Йеннифэр из Венгерберга or Трисс Меригольд.
Но если вы никогда не играли в Ведьмака — начнем сначала.
Главного героя зовут Геральт из Ривии
Геральт из Ривии — ведьмак, охотник на чудовищ
Nous avons séparé les noms des personnages en constantes, et désormais nous ne les orthographierons certainement plus et il ne sera plus nécessaire de les écrire à la main à chaque fois. Autre plus : si on a éventuellement besoin de changer la valeur d'une variable dans tout le programme, il suffit de le faire au même endroit, plutôt que de le refaire manuellement dans tout le code :)

Types immuables

Pendant que vous travaillez en Java, vous êtes probablement déjà habitué au fait que le programmeur contrôle presque entièrement l'état de tous les objets. Recherché - a créé un objet Cat. Si je le voulais, je l'ai renommé. S'il le voulait, il changeait d'âge, ou autre chose. Mais en Java, il existe plusieurs types de données qui ont un état spécial. Ils sont immuables , ou Immuables . Cela signifie que si une classe est immuable, l’état de ses objets ne peut pas être modifié. Exemples? Vous pourriez être surpris, mais l'exemple le plus célèbre de la classe Immutable est String! Il semblerait, ne pouvons-nous pas changer la valeur d'une chaîne ? Essayons:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1 = "I love Python";//но поведение str1 ниHow не влияет на str2
   System.out.println(str2);//str2 продолжает указывать на строку "I love Java", хотя str1 уже указывает на другой an object
}
Conclusion : J'aime Java J'aime Java Après avoir écrit :
str1 = "I love Python";
l'objet avec la chaîne "I love Java" n'a pas changé et n'est allé nulle part. Il existe en toute sécurité et contient exactement le même texte qu’auparavant. Code:
str1 = "I love Python";
je viens de créer un autre objet et maintenant la variable str1pointe vers lui. Mais nous ne pouvons en aucun cas influencer l’ objet « I love Java » . Bon, essayons différemment ! La classe Stringregorge de méthodes, et certaines d'entre elles semblent changer l'état de la ligne ! Par exemple, il existe une méthode replace(). Changeons le mot « Java » par le mot « Python » dans notre ligne !
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1.replace("Java", "Python");//попробуем изменить состояние str1, заменив слово "Java" на “Python”
   System.out.println(str2);
}
Conclusion : J'adore Java J'adore Java Ça n'a plus marché ! Peut-être que la méthode des courbes ne fonctionne pas ? Essayons-en un autre. Par exemple, substring(). Coupe une chaîne en fonction du nombre de caractères transmis. Réduisons le nôtre aux 10 premiers caractères :
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1.substring(10);//обрезаем исходную строку
   System.out.println(str2);
}
Conclusion : J'adore Java J'adore Java Immuable en Java : final, constantes et Immuable - 3 Rien n'a changé. Et cela n’aurait pas dû. Comme nous l'avons dit, les objets Stringsont immuables. Que sont alors toutes ces méthodes de classe String? Ils peuvent couper la ligne, en modifier les caractères, etc. Pourquoi sont-ils nécessaires alors si rien ne se passe ? Ils peuvent! Mais ils renvoient à chaque fois un nouvel objet chaîne. Cela ne sert à rien d'écrire :
str1.replace("Java", "Python");
- vous ne modifierez pas l'objet original. 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;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

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

   System.out.println(str1AfterReplacement);
}
C’est la seule façon dont Stringfonctionnent toutes ces méthodes. Vous ne pouvez rien faire avec l' objet "I love Java" . Créez simplement un nouvel objet et écrivez : "Nouvel objet = le résultat de quelques manipulations avec l' objet "I love Java " ." Quels autres types sont immuables ? D'après ce que vous devez absolument retenir maintenant : toutes les classes wrapper sur les types primitifs sont immuables. Integer, Byte, Character, Short, Boolean, Long, Double, Float- toutes ces classes créent des objets immuables . Cela inclut également les classes utilisées pour créer de grands nombres - BigIntegeret BigDecimal. Nous avons récemment passé en revue les exceptions et abordé StackTrace. Donc : les objets de la classe java.lang.StackTraceElement sont également immuables. C'est logique : si quelqu'un pouvait modifier les données de notre pile, cela pourrait annuler tout travail avec celles-ci. Imaginez que quelqu'un entre dans StackTrace et change OutOfMemoryError en FileNotFoundException . Et vous devriez travailler avec cette pile et rechercher la cause de l'erreur. Et le programme n'utilise pas du tout de fichiers :) Par conséquent, par mesure de sécurité, ces objets ont été rendus immuables. Eh bien, avec StackTraceElement , c'est plus ou moins clair. Pourquoi voudrait-on rendre les chaînes immuables ? Quel serait le problème s'il était possible de changer leurs valeurs. Ce serait probablement encore plus pratique :/ Il y a plusieurs raisons à cela. Premièrement, économiser de la mémoire. Des chaînes immuables peuvent être placées String Poolet les mêmes peuvent être utilisées à chaque fois au lieu d'en créer de nouvelles. Deuxièmement, la sécurité. Par exemple, la plupart des identifiants et mots de passe de n’importe quel programme sont des chaînes. La possibilité de les modifier pourrait entraîner des problèmes d'autorisation. Il existe d’autres raisons, mais nous ne les avons pas encore abordées dans l’apprentissage de Java ; nous y reviendrons plus tard.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION