Dans le langage de programmation "Java", "==" est pris en charge comme opérateur de comparaison pour l'équivalence, mais lorsqu'il est utilisé lors de la comparaison de ** types de référence ** qui ne sont pas des ** types primitifs ** tels que les types String Ce sera un résultat de traitement inattendu. L'essentiel est que vous ne devez pas utiliser l'opérateur d'égalité "==" pour comparer si les valeurs des types de référence ** sont égales. ** **
Dans cet article, j'écrirai sur les raisons pour lesquelles vous ne devriez pas utiliser d'opérateurs d'égalité lorsque vous effectuez des comparaisons de type String et ce qui se passe si vous le faites. Cependant, cette fois, l'article se concentre uniquement sur le type String, mais c'est aussi l'histoire du type référence en général.
Les types primitifs sont des types qui représentent les données elles-mêmes et n'ont aucun comportement pour manipuler les données. Vous ne pouvez pas affecter null à un type primitif.
Par exemple, il existe les types suivants.
Contrairement aux types primitifs, les types référence nécessitent l'utilisation de l'opérateur new pour créer et affecter des instances (entités) à des objets, chacun ayant un comportement spécifique au type. Vous pouvez affecter null au type de référence.
Par exemple, il existe les types suivants. De plus, le fabricant peut définir les types et les processus requis pour traiter l'application autres que les suivants.
Au fait, si vous étudiez une langue utilisant des pointeurs, vous la connaissez probablement déjà. Pour ceux qui disent «** Référence **» en premier lieu, il est recommandé car il est décrit en détail dans l'article suivant. https://qiita.com/hys-rabbit/items/2e94c8722dc8f950e77c
Tout d'abord, considérez le résultat de sortie en examinant le traitement suivant.
TestEquals.java
public final class TestEquals {
public static void main(String[] args) {
final String sequence1 = "test";
final String newSequence = new String("test");
System.out.println("Comparaison avec l'opérateur d'égalité 1:");
System.out.println(sequence1 == newSequence);
}
}
Maintenant, quel est le résultat de la comparaison de la même chaîne de caractères "test" avec l'opérateur d'égalité? À première vue, les mêmes chaînes de caractères sont comparées, de sorte que le résultat de la comparaison est probablement vrai. ** Cependant, dans le cas ci-dessus, le résultat de la comparaison sera toujours faux. ** **
Pourquoi obtenez-vous ce résultat? En effet, la comparaison avec l'opérateur d'égalité "==" détermine ** si les données sont stockées à la même adresse en mémoire **.
C'est une histoire technique, donc je n'entrerai pas dans les détails ici, mais il est important de se demander ce qu'est la mémoire. Cependant, dans cet article, je ne présenterai que quelques articles recommandés. Si vous pouvez vous le permettre en apprenant, vous voudrez peut-être jeter un coup d'œil.
** Mécanisme de gestion de la mémoire du tas Java ** https://www.atmarkit.co.jp/ait/articles/0504/02/news005.html
** Mémoire vue du programme ** https://qiita.com/shinpeinkt/items/55c0d30754482e8235b9
En d'autres termes, dans le cas ci-dessus, la variable "sequence1" et la variable "newSequence" sont stockées dans différentes zones de la mémoire, donc si vous comparez avec l'opérateur d'égalité, false sera renvoyé.
Fondamentalement, la compréhension ci-dessus est suffisante pour l'opérateur d'égalité, Dans certains cas, veuillez les vérifier également.
TestEquals.java
public final class TestEquals {
public static void main(String[] args) {
final String sequence1 = "test";
final String sequence2 = "test";
System.out.println("Comparaison avec l'opérateur d'égalité 2:");
System.out.println(sequence1 == sequence2);
}
}
La différence avec le premier exemple est que la variable "newSequence" a été initialisée à l'aide de l'opérateur new, mais la chaîne "test" est simplement affectée à la variable "sequence2". Quel sera le résultat du traitement dans les cas ci-dessus? Est-ce faux? ** Non, cela sera jugé vrai dans le cas ci-dessus. ** **
Cela est dû à une fonctionnalité Java, et je vais l'expliquer brièvement. Si vous initialisez en affectant la chaîne de caractères "test" à une variable puis initialisez en affectant la chaîne de caractères "test" à une autre variable de la même manière, elle sera gérée dans la même zone de la mémoire. Java a une fonctionnalité intégrée qui vous permet d'effectuer des ajustements comme si vous le faisiez. Par conséquent, dans le cas ci-dessus, le résultat du traitement est vrai.
Maintenant, parlons de la méthode equals définie dans la classe String principale. Pour rappel, utilisez la méthode equals comme suit:
TestEquals.java
public final class TestEquals {
public static void main(String[] args) {
final String sequence1 = "test";
final String sequence2 = "test";
System.out.println("Comparaison avec la méthode égale 1:");
System.out.println(sequence1.equals(sequence2));
final String newSequence = new String("test");
System.out.println("Comparaison avec la méthode égale 2:");
System.out.println(sequence1.equals(newSequence));
}
}
En comparant avec la méthode equals, true est renvoyé dans les deux modèles de l'exemple ci-dessus. Maintenant, qui est la méthode equals définie dans la classe String et quel type de traitement est défini?
Le code suivant est le traitement de la méthode equals définie dans la classe String.
String.java
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = length();
if (n == anotherString.length()) {
int i = 0;
while (n-- != 0) {
if (charAt(i) != anotherString.charAt(i))
return false;
i++;
}
return true;
}
}
return false;
}
À première vue, cela peut sembler difficile, mais si vous regardez comment cela fonctionne en le démontant, c'est une implémentation très simple.
Tout d'abord, la comparaison est effectuée avec l'opérateur d'égalité et true est renvoyé si les références sont égales. C'est le cas de l'initialisation en affectant directement une chaîne de caractères à une variable comme mentionné dans l'exemple précédent.
Ensuite, ce sera le processus de jugement lorsque la destination de référence est différente du bloc suivant. Tout d'abord, il détermine si l'instance de l'objet passé en argument est de type String, et si elle n'est pas de type String, elle renvoie false car ce sont des données complètement différentes en premier lieu. Ensuite, si l'objet argument est de type String, il est vérifié caractère par caractère depuis le début pour voir s'il est égal à la chaîne de caractères à comparer. Enfin, l'implémentation doit retourner true si tous les caractères sont égaux à la cible de comparaison.
De ce qui précède, vous pouvez voir que la méthode equals implémentée dans la classe String couvre toutes les faiblesses de la comparaison avec l'opérateur d'égalité que nous avons vu précédemment.
Si vous êtes à l'aise pour lire jusqu'ici, vous avez peut-être remarqué que si la classe String qui utilise la méthode equals devient nulle, une NullPointerException se produira toujours. Par conséquent, en tant qu'utilisateur Java, vous devez suivre les règles ci-dessous.
--Lors de l'utilisation de la méthode eauals, elle doit être sous la forme ** "Constante non nulle .equals (variable ou constante)" **
Autrement dit, l'implémenteur doit s'assurer que la classe String qui utilise la méthode equals n'est pas nulle. Bien sûr, en fonction de l'implémentation, il peut y avoir des situations où il ne peut pas être rendu constant, mais si vous garantissez toujours le traitement du programme, vous devez le concevoir de sorte que null n'entre pas.
J'écris ça depuis longtemps, mais comment était-ce? Je sais que certaines explications manquent, mais j'espère que cet article sera utile à ceux qui ont commencé à étudier la programmation avec Java.
https://morizyun.github.io/java/type-primitive-reference.html - Types primitifs et référence Java https://qiita.com/hys-rabbit/items/2e94c8722dc8f950e77c - Référence Java à comprendre dans la figure https://www.atmarkit.co.jp/ait/articles/0504/02/news005.html --Mécanisme de gestion de la mémoire du tas Java https://qiita.com/shinpeinkt/items/55c0d30754482e8235b9 --Mémoire vue depuis le programme