What is the difference between these two following statements?
String s = \"text\";
String s = new String(\"text\");
String str = new String("hello")
It will check whether String constant pool already contains String "hello"? If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
An object will be created in a heap memory area and str
reference points to object created in heap memory location.
if you want str
reference to point object containing in String constant pool then one has to explicitly call str.intern();
String str = "world";
It will check whether String constant pool already contains String "hello"? If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
In both the above case, str
reference points to String "world"
present in Constant pool.
Sorry for late Answer but much needed Answer. First we need to know some Java.lang.String Class rules.
String Literals e.g.String str="java";
(we use only double Quotes)
are different from String Object (we use new keyword)
e.g. String str=new String("java");
String is Immutable Object i.e. If value changes a new Object is created and returned to you eg See replace() and replaceAll()
functions and many more.
This creates a problem of many String Object in Modification, So creators of Java came up an Idea was called StringPool. StringPool is stored in heap area where object reference data will be stored as we know String is Char[]
(before java 9 very Long to read) or byte
[](after java 9 short to read).
String literals are stored in StringPool and String Objects are stored in as usual heap Object Area.
If there are many Object String Initialization JVM heap will be finished in String Operations only, Java Development team came up with intern() solution this moves/changes memory reference to StringPool.
Program: Comparing String references to objects
Another good link to understand java.lang.String better
import java.util.*;
class GFG {
public static void main(String[] args)
{
String siteName1 = "java.com";
String siteName2 = "java.com";
String siteName3 = new String("java.com");
String siteName4 = new String("java.com").intern();
System.out.println("siteName1:::"+Integer.toHexString(System.identityHashCode(siteName1)));
System.out.println("siteName2:::"+Integer.toHexString(System.identityHashCode(siteName2)));
System.out.println("siteName3 creation Of New Object Without Interned:::"+Integer.toHexString(System.identityHashCode(siteName3)));//must be Diffrent bcoz new Object In Heap Area
System.out.println("siteName4 creation Of New Object With Interned:::"+Integer.toHexString(System.identityHashCode(siteName4)));//must be same MemoryAddress of siteName1,siteName2 and Interned, bcoz Objects Points to String pool Now
System.out.println(siteName1 == siteName2); // true
System.out.println(siteName1 == siteName3); // false this tells about lietral vs String Objects
String siteName5 = siteName3.intern(); // Interning will not change Original Object but gives us a new Object
System.out.println("siteName5 Interned from siteName3:::"+Integer.toHexString(System.identityHashCode(siteName5)));//must be same MemoryAddress of siteName1,siteName2 and Interned, bcoz Objects Points to String pool Now
System.out.println(siteName1 == siteName3); // false this tells about Immutability
System.out.println(siteName1 == siteName5); // true After Intering both are same
System.out.println(siteName1 == siteName4); // true
System.out.println(siteName5 == siteName4); // true
}
}
One simple way to understand the difference is below:-
String s ="abc";
String s1= "abc";
String s2=new String("abc");
if(s==s1){
System.out.println("s==s1 is true");
}else{
System.out.println("s==s1 is false");
}
if(s==s2){
System.out.println("s==s2 is true");
}else{
System.out.println("s==s2 is false");
}
output is
s==s1 is true
s==s2 is false
Thus new String() will always create a new instance.
new String("text");
explicitly creates a new and referentially distinct instance of a String
object; String s = "text";
may reuse an instance from the string constant pool if one is available.
You very rarely would ever want to use the new String(anotherString)
constructor. From the API:
String(String original) : Initializes a newly created
String
object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.
Examine the following snippet:
String s1 = "foobar";
String s2 = "foobar";
System.out.println(s1 == s2); // true
s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
==
on two reference types is a reference identity comparison. Two objects that are equals
are not necessarily ==
. It is usually wrong to use ==
on reference types; most of the time equals
need to be used instead.
Nonetheless, if for whatever reason you need to create two equals
but not ==
string, you can use the new String(anotherString)
constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.
One creates a String in the String Constant Pool
String s = "text";
the other one creates a string in the constant pool ("text"
) and another string in normal heap space (s
). Both strings will have the same value, that of "text".
String s = new String("text");
s
is then lost (eligible for GC) if later unused.
String literals on the other hand are reused. If you use "text"
in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).
Think of "bla"
being a magic factory like Strings.createString("bla")
(pseudo). The factory holds a pool of all strings yet created this way.
If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.
If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.
Manually creating new String("")
overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals()
which compares the character sequence instead of the object reference equality.