Maison > Questions et réponses > le corps du texte
巴扎黑2017-04-18 10:08:31
J'ai exécuté le code ci-dessus en utilisant respectivement JDK6 et JDK7, et les résultats sont les suivants :
JDK6: false, false
JDK7: false, false
Ce n'est ni vrai ni faux comme l'a dit la personne qui a posé la question. Je pense qu'il y a deux raisons principales :
La chaîne "java" est particulière, elle est fixée dans le pool constant
D'où le code
String str1 = new StringBuilder("ja").append("va").toString();
System.out.println(str1.intern() == str1);
str1.intern() renvoie un objet dans le pool constant, ce n'est donc pas le même objet que str1 sur le tas.
La chaîne "python" apparaît déjà dans le code, elle sera donc ajoutée au pool de constantes.
Dans la deuxième partie du code, parce que la constante littérale "python" apparaît, elle sera ajoutée au pool de constantes.
Et :
String str2 = new StringBuilder("python").append("").toString();
System.out.println(str2.intern() == str2);
La chaîne vide "" est ajoutée à la chaîne "python", cela équivaut donc à ne pas ajouter de nouvelle constante de chaîne, et str2.intern() renvoie toujours l'objet dans le pool de constantes.
En fait, la question ci-dessus peut être étendue, par exemple :
// 1
String str1 = new StringBuilder("ja").append("va1").toString();
System.out.println(str1.intern() == str1); // true
// 2
String str2 = new StringBuilder("python").append("").toString();
System.out.println(str2.intern() == str2); // false
Je viens de changer la première partie du code "StringBuilder("ja").append("va")" en "StringBuilder("ja").append("va1")". Quelle différence ce changement fera-t-il. ? Le résultat ?
Regardons le résultat de l'exécution sous JDK6 et JDK7 :
JDK6: false, false
JDK7: true, false
Pourquoi les résultats d'exécution du JDK6 et du JDK7 sont-ils différents ?
En fait, cela implique différentes implémentations de la méthode intern() dans différents JDK :
Dans le JDK6 et les JDK précédents :
intern() 方法会把首次遇到的字符串实例 **复制** 到永久代中, 然后返回永久代中的实例.
Pour JDK7 et supérieur :
当遇到第一次出现的字符串时, intern() **不再复制实例**, 而是在常量池中记录首次出现的实例的引用, 并且 intern() 返回的是此实例引用.
Selon la différence entre les méthodes intern() du JDK6 et du JDK7, on connaît l'exemple :
// 1
String str1 = new StringBuilder("ja").append("va1").toString();
System.out.println(str1.intern() == str1); // true
// 2
String str2 = new StringBuilder("python").append("").toString();
System.out.println(str2.intern() == str2); // false
La raison pour laquelle différents résultats sont renvoyés dans différents JDK :
Dans JDK6, "java1" est la première constante de chaîne qui apparaît, elle sera donc copiée dans le pool de constantes et la méthode intern() renvoie l'objet dans le pool de constantes est donc différent de str1 sur le tas.
Dans JDK7, "java1" est la première constante de chaîne qui apparaît, mais la méthode intern() fait uniquement référence à cet objet. L'ajout au pool de constantes ne copie pas de a. nouvel objet dans le pool constant comme JDK6, donc la référence renvoyée par la méthode intern() est en fait toujours égale au str1 d'origine.