2009-10-18 7 views

Répondre

2

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. 
} 

http://en.wikipedia.org/wiki/String_interning

+0

appris un nouveau concept - interner! – lft93ryt

1

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.

+0

'a.equals (b)' ne sera pas compilé si 'a' est un type primitif. – ajb

7

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 classe java.lang.Object définit equals(other) comme étant this == 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 contrat java.lang.Object) il n'y a aucune garantie que cela soit significatif.

Pour (vrai) types primitifs:

  • == compare les valeurs du type et
  • equals() et toString() 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 et
  • toString() 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?.)

+0

'==' 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

+1

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" ... –

Questions connexes