There is a question like this:
How many objects are created by new String("aaa")? The answer is to create one or two. The reason is that if the aaa variable exists in the constant area, only one is created in the heap; if the aaa variable does not exist in the constant area, one is created in the constant area and one in the heap.
But the results of my actual test are inconsistent:
String s1 = new String("aaa");
String s2 = "aaa";
System.out.println(s1 == s2); //false
If new String("aaa") creates objects in both the heap and the constant area, then why doesn't s2 directly reuse the reference to the constant pool of s1?
Supplement:
I found that I thought wrongly. s1 should point to the element in the heap, and s2 points to the constant pool, so it is correct that the two are not equal. Is there any way to test the new? String("aaa") also creates objects in the constant pool at the same time?
Or String s3 = "aa".concat("a"); Does this s3 point to the heap or the constant pool? Can it reuse variables in the constant pool?
String s1 = new String("aaa");
String s2 = "aaa";
System.out.println(s1 == s2); //false
System.out.println(s1.intern() == s2); //true
When a String instance calls the intern() method, it will check whether there is the same string constant in the constant pool. If so, its reference will be returned. If not, a string equal to str will be added to the constant pool and Return its reference. Since s2 is already in the constant pool, s1.intern() will not create it again, but directly reference the same "aaa".
If this isn’t obvious enough, let’s experiment,
public class Cons {
public static void main(String[] args) throws InterruptedException {
String s1 = new String("vv");
}
}
Then command line
Note that the constant pool has VV
String a = "aaa" will create an object in the constant pool. If the same object exists in the constant pool, then a will directly point to the object. And String a = new String("aaa"), if it exists in the constant pool, it will not be created in the constant pool, but only in the heap.
String a = new String("aaa");
String b = new String("aaa");
System.out.println(a == b);//比較兩者堆中的引用返回false
System.out.println(a.intern() == b.intern());//比較兩者常量池中的引用,返回true
Find the answer from the source code. String s3 = "aa".concat("a"); is actually equivalent to String s3 = new String("aaa"), which will create an object in the heap.
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
String doesn’t create a new String object instance every time it is assigned a value? That's why there is StringBuilder.
According to object-oriented thinking, String itself may know best whether to create objects in the constant pool at the same time. Well, it has an intern() method.
The answers from the previous few are already very good. Let me add that what we often say "putting the string into the constant pool" refers to putting the reference of the string into the string constant pool (String Pool, which is essentially a hash table), the string itself is still placed on the heap.
// new一次就是在堆中創(chuàng)建一個新的對象。不new的話aaa直接在字符串常量中取值;
// String s2 = "aaa"; 先在內(nèi)存中尋找aaa,如果有,則將aaa的內(nèi)存首地址指向了s1,
如果沒有則在堆中中創(chuàng)建一個新的對象。
// String s1 = new String("aaa");//
// 不管"aaa"在內(nèi)存中是否存在,都會在堆中開辟新空間,將字符串"aaa"的內(nèi)存首地址指向s1。
String a = "aaa";// aaa在常量池中創(chuàng)建一個對象,將內(nèi)存首地址指向了a
String b = "aaa";// 直接aaa已經(jīng)存在的內(nèi)存首地址指向b。
String c = new String("aaa");// 不管存在與否,在堆中創(chuàng)建1個空間,內(nèi)存首地址與常量池中的地址完全不同
System.out.println(a==b);// true
System.out.println(a==c);// false