Comment la méthode toString()
, l'opérateur ==
et la méthode equals()
fonctionnent différemment ou de manière similaire sur les types de référence et les types primitifs?Comment les méthodes d'objet toString(), ==, equals() fonctionnent-elles différemment ou de manière similaire sur les types de référence et les types primitifs?
Répondre
Pour les types de référence, == compare la référence réelle (où se trouve la mémoire de l'objet) où, en tant que méthode égale, effectue une comparaison des données.
La JVM va parfois "internaliser" vos chaînes immuables pour des raisons de performances. Causer ceci:
String a = "abc";
String b = "abc";
if (a == b){
//The if statement will evaluate to true,
//if your JVM string interns a and b,
//otherwise, it evaluates to false.
}
L'opérateur « == » fonctionne sur le type primitif que vous avez, que dans le cas des objets de référence est la référence elle-même. C'est a == b
va comparer les valeurs pour les types primitifs int, mais va comparer la référence (pas la valeur) pour les types de référence. Deux objets de type référence qui ne sont pas identiques mais qui ont la même valeur renverront true
lorsque la méthode equals()
sera appelée, mais a == b
sera false.
Pour les types primitifs, lors de l'appel d'une méthode, le type est préalablement converti (encadré) en un type de référence, puis la méthode est appelée. Cela signifie que pour les types primitifs a == b
donnera la même valeur que a.equals(b)
, mais dans le dernier cas, deux objets encadrés temporaires sont créés avant d'appeler la méthode equals()
. Cela rendra l'opération plus coûteuse en temps CPU, ce qui peut ou non être un problème selon l'endroit où cela se produit. Autrement dit, pour comparer des valeurs de type primitif, vous devez utiliser ==
, tandis que pour comparer les valeurs de type de référence, vous devez utiliser la méthode .equals()
.
La même chose se produit avec la méthode toString()
. Lorsqu'il est appelé sur un objet de type référence, il appelle la méthode appropriée et produit une chaîne. Lorsqu'il est appelé sur un type primitif, le type sera autoboxé, puis la méthode sera appelée dans l'objet temporaire. Dans ce cas, vous pouvez appeler la méthode statique toString()
appropriée (c'est-à-dire pour l'appel int Integer.toString(myint)
) afin d'éviter de créer l'objet temporaire.
'a.equals (b)' ne sera pas compilé si 'a' est un type primitif. – ajb
Pour les types réguliers (y compris String):
==
compare les références d'objet. Il teste si deux références d'objet sont égales; c'est-à-dire s'ils se réfèrent au même objet.equals(Object)
si cet objet est "égal à" un autre. Ce que signifie «égal à» dépend de la façon dont la classe de l'objet définit l'égalité. La classejava.lang.Object
définitequals(other)
comme étantthis == other
, mais de nombreuses classes remplacent cette définition.toString()
fournit une conversion simple de l'objet en chaîne. Le format et le contenu de la chaîne résultante sont spécifiques à la classe et (du point de vue du contratjava.lang.Object
) il n'y a aucune garantie que cela soit significatif.
Pour (vrai) types primitifs:
==
compare les valeurs du type etequals()
ettoString()
ne sont pas définis. Java ne vous permet pas d'appeler une méthode sur une valeur primitive.
Cependant ceci est compliqué par le fait que dans certains contextes le langage Java dit qu'un type primitif peut être « autoboxed » pour donner une instance de type d'emballage correspondant du type primitif; par exemple. int
correspond à java.lang.Integer
, et ainsi de suite. Pour les classes d'emballage:
==
est défini le même que pour tout autre type de référence,equals()
compare les valeurs enveloppées ettoString()
formate les valeurs enveloppées.
La clé dans les travaux est illustrée par ce qui suit:
int a = ...
int b = a;
Integer aa = a; // autoboxing occurs
Integer bb = b; // autoboxing occurs
assert a == b; // always succeeds
assert aa.equals(bb); // always succeeds
assert aa == bb; // sometimes succeeds, sometimes fails.
La raison pour laquelle le dernier est échoue parfois que la JLS ne garantit pas que autoboxing une valeur primitive donnée sera toujours donner le même emballage objet. Il le sera dans certains cas (par exemple pour de petits entiers), et ne le sera pas pour d'autres (par exemple de grands entiers).
La leçon à tirer de l'exemple ci-dessus est que vous devez faire très attention en utilisant ==
sur un type de référence. Ne l'utilisez que lorsque vous vraiment voulez tester si deux références sont au même objet. Ne l'utilisez pas si vous voulez juste tester si les objets sont "égaux" sans le surcoût d'appeler equals()
.
(Notez également que String
est un autre type où ==
va vous donner la mauvaise réponse dans de nombreuses situations, voir How do I compare strings in Java?.)
'==' sur les primitives vérifie uniquement les valeurs et ignore les types. 'int x = 5; long y = 5L; octet b = 5; x == y; b == x; 'Les deux retournent vrai. – arun
Il n'ignore pas les types. L'un ou l'autre des opérandes est promu au type de l'autre. D'ailleurs, j'ai dit "valeurs du type" ... –
- 1. Utilisation des propriétés pour les types primitifs
- 2. Types primitifs et conteneurs IoC
- 3. Comment remplacer les méthodes de types imbriqués?
- 4. Surcharge d'une méthode pour prendre en charge les types de référence et les types nullables
- 5. Object Méthodes d'extension sur les types de valeur
- 6. Ignorer les méthodes sur les types d'entités avec NHibernate
- 7. Débogueur Xcode: Afficher l'adresse mémoire pour les types primitifs?
- 8. Les types de données primitifs dans PHP sont-ils transmis par référence?
- 9. Méthodes et types anonymes
- 10. méthodes génériques dans les types non génériques
- 11. Les méthodes d'extension pour les types génériques spécifiques
- 12. Génériques: les contraintes sur les types nullables
- 13. Liste de fait des types primitifs utilisables en C++
- 14. Déduction des types de référence dans les fonctions de gabarit
- 15. PostgreSQL et les types de données C#
- 16. Types de référence Linq2SQL
- 17. Choisissez entre les types de données et les méthodes de correspondance d'appel?
- 18. Types de référence dans .NET
- 19. Quelles sont les limitations des types de caractères primitifs dans D?
- 20. Dois-je initialiser TOUS les types de données primitifs à des valeurs 'sûres' dans Obj-C?
- 21. Les DataContracts de WCF doivent-ils être des types de valeur ou de référence?
- 22. Comment convertir les types PowerBASIC en types VB6?
- 23. cx_Oracle et les types définis par l'utilisateur
- 24. Types pour les grands nombres
- 25. Méthode de surcharge avec les types C#
- 26. Comment utiliser les différents types de nombres dans l'objectif C
- 27. Powershell, les services Web et les types d'objet
- 28. Types de référence de copie profonde
- 29. Quels sont les types de chaînes les plus utilisés en C++ et comment les convertir?
- 30. Une grande table ou des tables séparées pour stocker les avis sur les types de pièces?
appris un nouveau concept - interner! – lft93ryt