2009-12-13 7 views
5
public class A { 

    static String s1 = "I am A"; 

    public static void main(String[] args) { 
     String s2 = "I am A"; 
     System.out.println(s1 == s2); 
    } 
} 

Au-dessus du programme, sorties "true". Les deux sont deux identifiants/objets différents comment la sortie est "vrai"?Question Java de base: Égalité de chaîne

Ma compréhension est que la JVM créera une référence différente pour chaque objet, si oui, comment la sortie est vraie?

Répondre

20

Java gère un pool littéral String. Il réutilise ces littéraux quand il le peut. Par conséquent, les deux objets sont en fait le même objet String et == renvoie true.

Je crois que ce qu'on appelle string interning

+1

Pour plus d'informations sur le pool de chaînes, jetez un oeil à wikipedia: http://en.wikipedia.org/wiki/String_interning (+1 même idée) –

+1

Oui, les littéraux de chaîne sont automatiquement internés, conformément à la méthode interne API - http : //java.sun.com/javase/6/docs/api/java/lang/String.html – Ash

+1

Ce ne sont pas seulement les littéraux qui sont internés, mais aussi les constantes de compilation. –

1

Vous ne comparez pas le contenu des chaînes. Vous comparez seulement les références de l'objet. Vous devez utiliser la méthode equal (qui est un membre de la classe String). Soit cela ou vous pouvez utiliser la méthode compareTo (également sous la même classe String) pour vérifier si la valeur de retour est zéro.

Veuillez noter que le texte ci-dessus était plus une forte suggestion à l'état original de la question car il semblait que le PO ne connaissait pas le processus en cours dans les coulisses.

Les autres gars qui suggèrent l'internalisation ont raison. Pour répondre à cette question, je n'ai pas eu le temps d'aller au livre Java Puzzlers. J'ai soupçonné quelque chose au sujet de la définition de la même référence au moment de la compilation, mais je ne savais pas non plus comment trouver une référence à cela.

+0

Si je compare le contenu alors la réponse est certainement « vrai » Mais ici, les deux sont deux variables différentes, a remporté 't jvm crée deux références différentes? – novice

+1

@Felix Non, il compare des références, et la sortie est vraie - ce qui est exactement le résultat un peu surprenant qui a suscité cette question –

+2

Pourquoi avez-vous mar ked une réponse correcte? –

5

Parce que le Java Language Specification dit:

littéraux de chaîne ou, plus généralement, des chaînes qui sont les valeurs de expressions constantes (§15.28) -Y at "interné" afin de partager des instances uniques , en utilisant la méthode String.intern.

6

== vérifie que les variables pointent exactement sur la même instance d'un objet. Les deux littéraux que vous avez créés pointent vers le même endroit en mémoire et sont donc égaux. Les littéraux de chaîne sont internés de sorte que le même littéral de chaîne soit le même objet en mémoire.

Si vous deviez faire

String s = new String("foo"); 
String t = new String("foo"); 

Alors == retournerait faux et s.equals (t) retournera vrai.

5

Il est à cause d'une optimisation de la mémoire réalisée par le compilateur ... à savoir String constantes (ie - String s faites par le même String littéral) utilisent le même objet String depuis Strings sont immuables. L'opérateur == vérifie simplement que deux objets sont le même objet réel.

Si vous pouvez vous procurer le livre Java Puzzlers de Joshua Bloch et Neal Gafter, et regardez le puzzle 13, "Animal Farm" ... il a de bons conseils sur cette question. Je vais copier un texte pertinent:

« Vous savez sans doute que les constantes à la compilation de type String sont internées [JLS 15,28] En d'autres termes, les deux expressions constantes de type String qui désignent la même séquence de caractères sont. représenté par des références d'objet identiques ...Votre code devrait rarement, voire jamais, dépendre de l'internement des constantes de chaîne. Interning a été conçu uniquement pour réduire l'empreinte mémoire de la machine virtuelle, pas comme outil pour les programmeurs ... Lorsque vous comparez des références d'objet, vous devez utiliser la méthode equals plutôt que l'opérateur == sauf si vous devez comparer l'identité de l'objet plutôt que sa valeur .. »

C'est de la référence ci-dessus ... je l'ai mentionné pages 30 -. 31 dans mon livre

+1

Je l'ai mentionné [je n'ai pas mentionné pourquoi il l'a fait], et j'ai été critiqué pour cela. – monksy

+0

+1 Pour mentionner Puzzlers et une explication pourquoi – monksy