I recently learned that in Java: == compares the object references, not the content, which is why:
String str1 = "hell";
String str2 = "o";
String str3 = str1 + str2;
String str4 = "hello";
str3 == str4; // False
So far so good. However when I do the following:
String str5 = "hello";
str5 == str4; // True
Does this mean that str5 and str4 reference the same memory object? How does this work?
The String str5 = "hello"; creates a pooled String value hello, which is why str5 == str4 returns true.
On the other hand, str1 + str2 works like this:
An instance of the StringBuilder class is created (behind the scenes)
The + operator actually invokes the StringBuilder#append(String s) method
When the appending is done, a StringBuilder.toString() method is invoked, which returns a brand new String object. This is why str3 == str4 is actually false.
More info:
How do I compare Strings in Java?
How Java do the string concatenation using “+”?
Yes. str5 and str4 refer the same memory object. As Strings are immutable when you change the value of some string its produce an different object. If two String objects have the same value then second one is not created, JVM just give the reference of the first object.
When the value of String changed different object created for some security and other usefull purpose read these link:
Immutability of Strings
wiki Immutable object
When some string are created like
String str1="hello";
JVM creates an immutable object when again you try to create some string with same value
String str2="hello"
JVM use the same procedure to create an object as see's that this object is already created then its return the object of the str1 to reduce duplicate object creation.
This will be useful string pool in the jvm
Yes, when you create and assign a String value eg String s1="hello"; , it gets added in the String pool. Now if you assign the same String value to another reference like this:-
String s2="hello";
The variable s2 will point to the same String object hello , present in String pool.
However you can force and create a new String object for the same values like this:-
String s3= new String("hello");
This will add and create new object for hello even though it is already present in the String pool.
Hence it can be summarised as:-
s1==s2; //return true
s1==s3; //return false
s2==s3; //returns false
Strings are pooled by the JVM once they are created, that's why those variables refer to the same instance in the String pool.
And the idea behind having a String pool is to avoid unnecessary object creation.
Strings are immutable objects. This is why str1 and str2 combined are not equal to str3.
Ya,its gives true for str5 ==str4 becoz it uses"string pool area" to store."this time also it
compares object references" but these strings has same object reference as string pool area has one object id.
In first case strings are not created in string pool area thats why it gives false.
A private pool of string literals is maintained by String class. All literal strings and string-valued constant expressions are added to this pool during program start up. So all string literals with same value will point to same object.
When a new string object is created(e.g. by concatenating two string objects) it does not belong to the String pool, so comparing it with another string literal will return false. Any string object can be added to String pool by invoking intern() method on that string object, now the object will point to a string literal from the pool which have same value as this object. Now any string comparison of this object with same string literal will yield true.
Related
String is Immutable (Fact)
Lets say I have two objects of string given below:
String str1 = new String("dave");
String str2 = new String("dave");
While compiling, Interning of string objects happens. And according to Wikipedia, It says "string interning is a method of storing only one copy of each distinct string value, which must be immutable. All compile-time constant strings in Java are automatically interned using this method."
If that's a case, then what would happen to my two references str1 and str2 ? To which object they will point out once compiled ?
I hope its valid question, otherwise correct me, I'm confused little bit.
Below both str1 and str2 are created on heap, because you are creating them at run time. Even both objects are created at different references.
String str1 = new String("dave");
String str2 = new String("dave");
Even str1 == str2 will return false. Their values are same but they are two different objects on heap.
However if you create the object at compile time, as example
String str1="dave";
String str2="dave";
then str1 == str2 will return true, because both these objects are
part of same reference created at compile time in string pool.
When we use double quotes to create a String, it first looks for String with same value in the String pool, if found it just returns the reference else it creates a new String in the pool and then returns the reference.
I know there are two ways of creating String in Java:
String a = "aaa";
String b = new String("bbb");
With the first way Java will definitely create a String object in the string pool and make a refer to it. (Assume "aaa" wan't in the pool before.)
With the second method, an object will be created in the heap, but will jvm also create an object in the string pool?
In this post Questions about Java's String pool, #Jesper said:
If you do this:
String s = new String("abc");
then there will be one String object in the pool, the one that represents the literal "abc", > and there will be a separate String object, not in the pool, that contains a copy of the > content of the pooled object.
If that's true, then every time with the new String("bbb");, a object "bbb" is created in the pool, which means by either way above, java will always create a string object in the pool. Then what is intern() used for ? In the docs http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern(), it says:
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
That means there are cases that a string is not in the pool, is that possible ? Which one is true ?
As you know that String is an immutable object in Java programming language, which means once constructed can not be altered. Due to this, JVM has the ability to maintain a literal pool which is helpful to reduce the memory usage and to increase the performance. Each time when a String literal is used JVM checks the literal pool. If the literal is already available, the same reference would be returned. If the literal is not available, a new String object will be created and added in the literal pool.
This theory is applied when you try to create a String like a primitive or a literal/constant.
String str = "bbb";
But when you create a new String object
String str = new String("bbb");
the above mentioned rules are overridden and a new instance is created always.
But the intern API in the String class can be used to pick the String reference from the literal pool even though you create a String using new operator. Please check the below given example. Although the str3 is created using new operator since we used the intern method JVM picked up the reference from the literal pool.
public class StringInternExample {
public static void main(final String args[]) {
final String str = "bbb";
final String str1 = "bbb";
final String str2 = new String("bbb");
final String str3 = new String("bbb").intern();
System.out.println("str == str1 : "+(str == str1));
System.out.println("str == str2 : "+(str == str2));
System.out.println("str == str3 : "+(str == str3));
}
}
Output of above code:
str == str1 : true
str == str2 : false
str == str3 : true
You can have a look: Confusion on string immutability
Source of answer: http://ourownjava.com/java/java-string-immutability-and-intern-method/
Shishir
There are essentially two ways that our String objects can enter in to the pool:
Using a literal in source code like "bbb".
Using intern.
intern is for when you have a String that's not otherwise from the pool. For example:
String bb = "bbb".substring(1); // substring creates a new object
System.out.println(bb == "bb"); // false
System.out.println(bb.intern() == "bb"); // true
Or slightly different:
System.out.println(new String("bbb").intern() == "bbb"); // true
new String("bbb") does create two objects...
String fromLiteral = "bbb"; // in pool
String fromNewString = new String(fromLiteral); // not in pool
...but it's more like a special case. It creates two objects because "bbb" refers to an object:
A string literal is a reference to an instance of class String [...].
Moreover, a string literal always refers to the same instance of class String.
And new String(...) creates a copy of it.
However, there are many ways String objects are created without using a literal, such as:
All the String methods that perform some kind of mutation. (substring, split, replace, etc.)
Reading a String from some kind of input such as a Scanner or Reader.
Concatenation when at least one operand is not a compile-time constant.
intern lets you add them to the pool or retrieve an existing object if there was one. Under most circumstances interning Strings is unnecessary but it can be used as an optimization because:
It lets you compare with ==.
It can save memory because duplicates can be garbage collected.
Yes, new String("abc") will create a new object in memory, and thus it is advised to avoid it. Please have a look at item 5 of Josh Bloch's Effective Java, "Avoid creating unnecessary objects" where it is better explained:
As an extreme example of what not to do, consider this statement:
String s = new String("stringette"); // DON'T DO THIS!
The statement
creates a new String instance each time it is executed, and none of
those object creations is necessary. The argument to the String
constructor ("stringette") is itself a String instance, functionally
identical to all of the objects created by the constructor. If this
usage occurs in a loop or in a frequently invoked method, millions of
String instances can be created needlessly. The improved version is
simply the following:
String s = "stringette";
This version uses a
single String instance, rather than creating a new one each time it is
executed. Furthermore, it is guaranteed that the object will be reused
by any other code running in the same virtual machine that happens to
contain the same string literal [JLS, 3.10.5].
http://uet.vnu.edu.vn/~chauttm/e-books/java/Effective.Java.2nd.Edition.May.2008.3000th.Release.pdf
With the second method, an object will be created in the heap, but will jvm also create an object in the string pool?
Yes, but it is the string literal "bbb" which ensures the interned string1. The string constructor creates a new string object which is a copy with the same length and content - the newly created string is not automatically interned.
If that's true, then every time with the new String("bbb");, a object "bbb" is created in the pool, which means by either way above, java will always create a string object in the pool. Then what is intern() used for ?
Only string literals are automatically interned. Other string objects must be manually interned, if such is the desired behavior.
That means there are cases that a string is not in the pool, is that possible ?
With the exception of manual calls to String.intern, only string literals result in interned strings.
While I would recommend using a specialized collection for such cases, interning may be useful where it can be used to avoid creating extra duplicate objects. Some use-cases where interning can be beneficial - as in, the same string value can appear many times - is in JSON keys and XML element/attribute names.
1 This is trivial to reason, consider:
String _b = "bbb"; // string from string literal (this is interned)
String b = new String(_b); // create a NEW string via "copy constructor"
b == _b // -> false (new did NOT return an interned string)
b.equals(_b) // -> true (but it did return an equivalent string)
b.intern() == _b // -> true (which interns to .. the same string object)
Consider statement:
String s=new String("abc");
Will this statement creates two String objects namely "abc" and the one represented by 's'?
and if it creates two objects then will "abc" get stored in String pool or just discarded?
EDIT:
i am asking this question in reference to Difference between string object and string literal, where in the last two answers , creation of two objects is denied.
Avoid such kind of behavior , because "abc" is already a String and by making a new String, you are creating an unnecessary Object.
Instead go for String s = "abc";
This way, the String gets interned by the JVM and is added to a pool.
To answer your question, you are just creating an Object s that is referring to "abc".
So when you do say String t = new String("abc"); and then do s==t, will yield in false. Because they have their separate instances to abc.
String s = "HELLO";
Here "s" is a object reference variable of type String, which refers to the String literal object "Hello" which is added to the String Literal Pool.
String t = new String("Hello");
Here t is a object reference variable of type String, which refers to the String object "Hello" which is added to the String Pool.
Difference Between String Literal and String :
Assume
String s = "Hello";
String t = new String("Hello");
Now if following changes are done:
s = null;
t = null;
Hello String object associated with t will be a candidate for Garbage Collector, But Hello String Literal associated with s will NOT BE A CANDIDATE for Garbage Collector, as there will ALWAYS BE A REFERENCE FROM STRING LITERAL POOL to it.
I read in Kathy Sierra book that when we create String using new operator like String s = new String("abc") In this case, because we used the new keyword, Java will create a new String object in normal (nonpool) memory, and s will refer to it. In addition, literal "abc" will be placed in the pool.
intern() says that if String pool already contains a string then the string from the pool is returned Otherwise, the String object is added to the pool and a reference to this String object is returned.
If string "abc" when created using new also placed the string in the pool, then wht does intern() says that string from the pool is returned if String pool contains the string otherwise the string object is added to the pool.
Also I want to know if we create a String using new then actually how many objects get created?
TL;DR: If you ever really need to do new String("abc"), you'll know you need to and you'll know why. It's so rare that it's almost valid to say you never need to. Just use "abc".
The long version:
When you have the code new String("abc") the following things occur at various times:
When the class containing that code is loaded, if a string with the characters "abc" is not already in the intern pool, it's created and put there.
When the new String("abc") code is run:
A reference to the "abc" string from the intern pool is passed into the String constructor.
A new String object is created and initialized by copying the characters from the String passed into the constructor.
The new String object is returned to you.
If string "abc" when created using new also placed the string in the pool, then why does intern() says that string from the pool is returned if String pool contains the string otherwise the string object is added to the pool.
Because that's what intern does. Note that calling intern on a string literal is a no-op; string literals are all interned automatically. E.g.:
String s1 = "abc"; // Get a reference to the string defined by the literal
String s2 = s1.intern(); // No-op
System.out.println(s1 == s2); // "true"
System.out.println(s1 == "abc"); // "true", all literals are interned automatically
Also I want to know if we create a String using new then actually how many objects get created?
You create at least one String object (the new, non-interned one), and possibly two (if the literal wasn't already in the pool; but again, that bit happens earlier, when the class file's literals are loaded):
String s1 = "abc"; // Get a reference to the string defined by the literal
String s2 = new String(s1); // Create a new `String` object (guaranteed)
System.out.println(s1 == s2); // "false"
String s3 = s2.intern(); // Get the interned version of the string with these characters
System.out.println(s1 == s3); // "true"
String Pool is a pool of string references. Objects are created in Heap only.
When using new String("abc").intern() or using method like String s = "abc"; String pool is checked if there is an reference existing which refers to "abc".
In case reference for "abc" already exists in pool and .intern() is called on the reference referencing to an String object created using new String("abc"), then object created by new String("abc") is eligible for garbage collection. See below code for more clarity.
public static void main(String[] args) {
String s = new String("abc");
String a = s;
System.out.println(s==a);// true
String b = "abc";
s = s.intern();
System.out.println(s==a);// false
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java Strings: “String s = new String(”silly“);”
If i write
String s= new String("how many object b created by this method ");
how many reference objects and objects will be created in comparison to doing it this way:
Sting s1="Is this method is good as compare to upper";
Using String s= new String("how many object b created by this method "); creates a new object 's' of String class, and you are passing the string "how many object b created by this method" to its constructor.
In String s1="Is this method is good as compare to upper"; 's1' is a string literal. On string literals:
Each time your code
create 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 returns. If the string does
not exist in the pool, a new String
object instantiates, then is placed in
the pool. Java can make this
optimization since strings are
immutable and can be shared without
fear of data corruption.
source
The above concept is related to string interning; all literal strings and string-valued constant expressions are interned in Java [source]. So basically, using String s1="Is this method is good as compare to upper"; will create a new object only if "Is this method is good as compare to upper" is not already in the pool.
Using String s1="some string" doesn't create new String object. There is existing String object for every String literal already.
String literals with same values are represented with single String object, so if you use String s1="some string"; String s2="some string"; both s1, s2 refer to same "some string" object.
new String("...") creates one new String object, which uses same data as String object for value "..." passed to constructor.
Consider:
String s1 = new String("hi");
String s2 = new String("hi");
System.out.println(s1 == s2);
Will print false.
However
String s1 = "hi";
String s2 = "h1";
System.out.println(s1 == s2);
Will print true.
And
String s1 = "hi";
String s2 = new String("hi");
System.out.println(s1 == s2);
Will print false.
This is why you should always use String.equals when comparing Strings instead of ==.
But don't take my word for it... Check this excerpt from the Java Language Specification JLS 3.10:
Thus, the test program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { static String hello = "Hello"; }
produces the output:
true true true true false true
This example illustrates six points:
Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).
Literal strings within different classes in the same package represent references to the same String object.
Literal strings within different classes in different packages likewise represent references to the same String object.
Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
Strings computed by concatenation at run time are newly created and therefore distinct.
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.
There are two ways to create a String object in Java:
Using the new operator. For example,
String str = new String("Hello");
Using a string literal or constant expression). For example,
String str="Hello"; (string literal) or
String str="Hel" + "lo"; (string constant expression).
String Literal Pool :
String allocation, like all object
allocation, proves costly in both time
and memory. The JVM performs some
trickery while instantiating string
literals to increase performance and
decrease memory overhead. To cut down
the number of String objects created
in the JVM, the String class keeps a
pool of strings. Each time your code
create 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 returns. If the string does
not exist in the pool, a new String
object instantiates, then is placed in
the pool.
Creating a String object using NEW keyword always creates an object in the heap containing the desired string and the reference of the created object in the heap is returned.
Creating a String object without NEW keyword (using literal) first checks for an existing string with the same data in the String literal pool, if found, the same reference from the String literal pool is returned, else, a new one is created in the String literal pool and its reference is returned.