Java: 不同String 相加在内存里的分布?
迷茫
迷茫 2017-04-18 10:30:17
0
3
828
    String str1 = "a";
    String str2 = "b";
    String str3 = "ab";
    String str4 = new String("a");
    String str5 = new String("b");
    String str6= new String("ab");
    
    
    String plus1 = str1 + str2; 
    String plus2 = str1 + "b"; 
    String plus3 = str4 + "b";
    String plus4 = "a" + "b";
    String plus5 = str4 + str5;
    String plus6 = str4 + str2;

string相加有上面的6种情况
我想弄清楚各种情况的区别,我知道的是plus4都是在栈区,所以结果是一个字符串常量池里的常量,但是其他情况呢?
另外,我打印plus1~plus6的地址或者hashcode,发现都是一样的,怎么回事?

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

répondre à tous(3)
Ty80

La réponse au premier étage est trop générale, et parler d'allocation de mémoire quelles que soient les versions de JVM et JDK n'est qu'un voyou.

Prenons la question comme exemple :

String str1 = "a";
String str2 = "b";
String str3 = "ab";

Ce type de définition directe d'une chaîne, la JVM considère la chaîne comme un invariant, c'est-à-dire thread-safe, car ce type de chaîne est directement alloué dans le pool de constantes dans la zone des méthodes.

String str4 = new String("a");
String str5 = new String("b");
String str6= new String("ab");

a le nouveau mot-clé, indiquant que cette chaîne est allouée sur le tas. Vous pouvez utiliser la méthode suivante pour vérifier :

public static void main(String[] args) {
    String str1 = "a";
    String str2 = "b";
    String str3 = "ab";
    
    String str4 = new String("a");
    String str5 = new String("b");
    String str6= new String("ab");
    
    System.out.println(str1 == str4);   // false,说明str1和str4的内存地址不一样,一个在方法区,一个在堆.
    System.out.println(str1 == str4.intern());  // true,str4存入常量池后并没有重新创建一块内存,而是使用了已有的常量句柄.
    }

Répondez pourquoi les codes de hachage de plus1~6 sont les mêmes. C'est parce que vous n'avez pas remplacé la méthode de hachage de String. L’implémentation du hashcode par défaut de String est :

@Override public int hashCode() {
    int hash = hashCode;
    if (hash == 0) {
        if (count == 0) {
            return 0;
        }
        for (int i = 0; i < count; ++i) {
            hash = 31 * hash + charAt(i);
        }
        hashCode = hash;
    }
    return hash;
}

Seules les constantes littérales sont traitées, et les constantes littérales de plus1~6 sont les mêmes, donc les valeurs du hashcode sont bien sûr les mêmes. Ensuite, le hashcode est cohérent, ce qui ne signifie pas que les adresses mémoire allouées par eux dans la jvm sont cohérentes.

左手右手慢动作

Il n'y a qu'une seule instance de la même chaîne en mémoire

---------------------------------Ligne de séparation------------ --- -

Cette réponse est trop générale et trompeuse. Veuillez vous référer à la réponse de frère Yi

大家讲道理

Ce que vous avez dit ci-dessus est vrai, le même littéral de chaîne n'aura qu'une seule valeur dans la zone de méthode. Il s’agit de la différence d’utilisation communément mentionnée entre string et stringbuffer.

J'ajouterai ci-dessous :
String str4 = new String("a");
Le littéral "a" est stocké dans la zone méthode du jvm.
L'objet str4 est stocké dans le tas.
La phrase ci-dessus signifie que 2 adresses mémoire sont allouées.
La pile stocke 8 types de base et returnAddress et reference Les chaînes ne seront pas stockées dans la pile.
Quant à l'utilisation du hashcode, il est utilisé pour la correspondance et le positionnement. Vous pouvez vous rendre sur Baidu vous-même pour découvrir la différence entre hashcode et == et égal.
De plus, les adresses mémoire de plus1-6 sont définitivement différentes. Je ne sais pas comment tu as trouvé que c'était pareil. . .

S’il y a quelque chose que je ne comprends pas correctement, donnez-moi quelques conseils.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal