31 votes

le comportement des littéraux String est déroutant

Le comportement de littéraux de Chaîne est très confuse dans le code ci-dessous.

Je peux comprendre la ligne 1, la ligne 2 et la ligne 3 sont true,, mais pourquoi est-ligne 4 false?

Lorsque j'imprime le hashcode de les deux sont de la même

package a;

class Hello
{
   public static void main(String[] args)
   {
      String hello = "Hello", lo = "lo";
      System.out.print((a.Other1.hello == hello) + " ");     //line 1
      System.out.print((a.Other1.hello == "Hello") + " ");   //line 2
      System.out.print((hello == ("Hel"+"lo")) + " ");       //line 3
      System.out.print((hello == ("Hel"+lo)) + " ");         //line 4
      System.out.println(hello == ("Hel"+lo).intern());      //line 5
      System.out.println(("Hel"+lo).hashCode());   //hashcode is 69609650 (machine depedent)
      System.out.println("Hello".hashCode());       //hashcode is same WHY ??.
   }
}

class Other1 { static String hello = "Hello"; }

Je sais qu' == vérifie la référence de l'égalité et de vérifier dans la piscine pour les littéraux. Je sais égale est la bonne façon. Je veux comprendre le concept.

J'ai déjà vérifié cette question, mais elle n'explique pas clairement.

Je vous serais reconnaissant une explication complète.

26voto

Joachim Sauer Points 133411

Chaque moment de la compilation expression constante de type String seront placés dans la Chaîne de la piscine.

Essentiellement, cela signifie que: si le compilateur peut (facilement) "calculer" la valeur de l' String sans exécuter le programme, puis il sera mis dans le bassin (les règles sont un peu plus compliquées que cela et avoir quelques cas particuliers, voir le lien ci-dessus pour tous les détails).

C'est vrai pour toutes les Chaînes dans les lignes 1 à 3.

"Hel"+lo est pas une constante de compilation de l'expression, parce qu' lo est un non-constant variable.

Les codes de hachage sont les mêmes, parce que le hashCode d'une Chaîne dépend seulement de son contenu. C'est exigé par le contrat de equals() et hashCode().

2voto

Chechulin Points 685

Les chaînes calculées par concaténation à l'exécution sont nouvellement créées et donc distinctes

voici un lien à lire: http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

1voto

Tom Points 13036

C'est parce que le comipler dans ce cas n'est pas assez intelligent pour comprendre qu'il peut graver dans le même littéral de chaîne.

Le code de hachage doit toujours renvoyer la même valeur pour les chaînes qui sont équivalentes (l'appel de .equals sur true renvoie true) et retournera donc le même résultat.

0voto

Ren Points 1143

Le hashCode n'a rien à voir avec une référence à un objet (la vérification == est un comparateur de référence). Il est possible d'avoir 2 objets où le hashCode renvoie la même valeur, l'opérateur égal renvoie vrai, mais == retourne faux. C'est quand ce sont 2 objets différents, mais avec la même valeur.

Je crois que la raison pour laquelle la ligne 4 renvoie false est qu'il s'agit d'une valeur calculée lors de l'exécution, et donc d'une instance de chaîne différente, avec une référence différente.

0voto

dinezhr Points 16

La différence entre le numéro de la ligne 3 et 4 sont comme suit.

•Les chaînes calculées par des expressions constantes sont calculés au moment de la compilation, puis traitées comme si elles étaient des littéraux.

•Les chaînes calculée par concaténation au moment de l'exécution sont nouvellement créé, et donc distinct.

La référence ci-dessus est tirée de java spec. S'il vous plaît laissez-moi savoir si vous avez besoin de plus de précisions.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X