Es gibt eine Frage wie diese:
Wie viele Objekte werden durch new String("aaa") erstellt? Die Antwort ist, eine oder zwei zu erstellen. Der Grund dafür ist, dass, wenn die aaa-Variable im Konstantenbereich vorhanden ist, nur eine im Heap erstellt wird. Wenn die aaa-Variable nicht im Konstantenbereich vorhanden ist, wird eine im Konstantenbereich erstellt und einer auf dem Haufen.
Aber die Ergebnisse meines tatsächlichen Tests sind inkonsistent:
String s1 = new String("aaa");
String s2 = "aaa";
System.out.println(s1 == s2); //false
Wenn new String("aaa") Objekte sowohl im Heap als auch im Konstantenbereich erstellt, warum verwendet s2 dann nicht direkt den Verweis auf den Konstantenpool von s1 wieder?
Ergänzung:
Ich habe fälschlicherweise gedacht, dass s1 auf das Element im Heap zeigen sollte und s2 auf das Element im Konstantenpool zeigen sollte. Es ist also richtig, dass die beiden nicht gleich sind new String("aaa") erstellt gleichzeitig auch Objekte im Konstantenpool?
Oder String s3 = "aa".concat("a"); Zeigt dieser s3 auf den Heap oder den Konstantenpool? Kann er Variablen im Konstantenpool wiederverwenden?
当一个String实例调用intern()方法时,会查找常量池中是否有相同的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个等于str的字符串并返回它的引用,由于s2已经在常量池中,所以s1.intern()不会再创建,而是直接引用同一个"aaa"。
如果这个还不够明显,那么我们就来试验,
然后命令行
注意常量池有 VV
问题一:
String a = “aaa”,会在常量池中创建对象,如果常量池中存在同样的对象,那a就直接指向该对象。而 String a = new String("aaa"),若常量池中存在,则不在常量池中创建,只在堆中创建。
问题二:
从源码中找答案String s3 = "aa".concat("a"); 其实就相当于 String s3 = new String("aaa"),会在堆中创建对象。
String不是每次赋值都重新创建一个String对象实例吗?所以才会有StringBuilder呀。
按照面向对象的思想,有没有同时在常量池创建对象,可能String自己最清楚,嗯,他有一个intern()方法。
前面几位的回答已经非常好了,我补充一句,我们经常说的“把字符串放到常量池”是指把字符串的引用放到字符串常量池(String Pool,本质是一个哈希表)中,字符串本身还是放在堆上的。