Join lines after changing a line

I have this code

String a="test"; String b="test"; if(a==b) System.out.println("a == b"); else System.out.println("Not True"); 

And every Java expert knows that here if(a==b) will be passed from the string merge tool .
According to String pooling
Each time your code creates a string literal, the JVM checks the string literal pool first. If the string already exists in the pool, a reference to the pooled instance is returned. If the string does not exist in the pool, a new String object is created and placed in the pool. JVM keeps at most one object of any String in this pool. String literals always refer to an object in the string pool
And that is why the condition has passed in the above code.
Now here is the question . In the above code, when I added two additional lines a+="1" and b+="1" , now the values โ€‹โ€‹of String a and b will be Test1 .
The new code will be like this:

 String a="test"; String b="test"; if(a==b) System.out.println("a == b"); else System.out.println("Not True"); a+="1"; //it would be test1 now b+="1"; //it would also be test1 now if(a==b) System.out.println("a == b"); else System.out.println("Not True"); 

Now, after changing the lines, when I placed the check if(a==b) , then it did not pass. I know this is due to the immutable feature of String. But I want to know

1) After the change, does the JVM support their two different objects?
2) Is the JVM called new String() to change any string?
3) Why don't they refer to any, even I tried to call intern() during the change?
Q3 Hint:
a+="1".intern();
b+="1".intern();

+4
source share
3 answers

1) Yes, why a == b fails. These newlines are not part of the string pool, as they were not literals from the start.

2) As @LuiggiMendoza noted, he will use the String constructor if the compiler has a way to find out the values โ€‹โ€‹of the strings, otherwise he will rather use StringBuilder internally (that at the end of the day he will use the String constructor to return the final string)

3) Even if "1" is a literal, the result is a + "1".intern(); By itself, it is not a literal, but a new String object created using the String constructor, so it is not added to the string pool.

+1
source

Since strings are immutable. After changing the string, your variable will now refer to another String .

When creating a new String JVM uses StringBuilder if the value is not known at compile time; otherwise, the standard String constructor is used.

When adding "1".intern() .intern() is applied to "1" ( not a + "1" ); concatenation creates new String objects ( NOT literals), so a and b do not refer to the same objects. Remember that when Strings is created using the new operator, you force new memory to be allocated.

In order for a and b actually refer to the same object, you will need to call .intern() for both of them:

 _a = _a.intern(); //adds _a to the String pool _b = _b.intern(); //makes _b point to the same object as _a, since _b.equals(_a) 
+1
source

This is because when you do "+ =", it creates a new object on the heap not in the string pool due to the immutability of String. If you want it in a String pool, then call the intern () method again for both lines.

 String a="test"; String b="test"; if(a==b) System.out.println("a == b"); else System.out.println("Not True"); a+="1"; //it would be test1 now b+="1"; //it would also be test1 now a=a.intern(); b=b.intern(); if(a==b) System.out.println("a == b"); else System.out.println("Not True"); 

Now it will generate 'a == b' in both cases. For more information on the row pool, go to this link .

+1
source

Source: https://habr.com/ru/post/1493581/


All Articles