This question already has answers here:
String equality vs equality of location
(6 answers)
What is the difference between == and equals() in Java?
(26 answers)
Closed 9 years ago.
Can anyone tell me how many objects are created. Does s3 not reference the same hello from string pool? how many String objects are there
/**
*
*/
package agnitio;
/**
* #author admin
*
*/
public class TestString {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1="hello";
String s2="hello";
String s3 = new String("hello");
System.out.println(s1==s2); // true
System.out.println(s1==s3); // false
System.out.println(s2==s3); // false
}
}
Only two objects are created. First object when you do :
String s1="hello";
No object is created in memory when you do :
String s2="hello";
This is because JVM String class is based on flyweight pattern so if a string already exist in memory as in your case "hello", so creating a new reference will not create a new object. Both s1 and s2 will point to the same memory location.
Second object is created when you do:
String s3 = new String("hello");
As new operator will always create a new object.
== compares whether both the references pointing to the same memory location or not. While equals compares the contents of strings. Having said that and as I mentioned both s1 and s2 are pointing to same memory location and hence both == and equals will return TRUE for their comparison. But s3 is a different object and hence comparison wiht s1 and s2 with == operation will return false. But if you do equals comparison of s1,s2 and s3, you will get TRUE.
No, imagine StringPool facility without making string immutable , its not possible at all because in case of string pool one string object/literal e.g. "hello" has referenced by many reference variables , so if any one of them change the value others will be automatically gets affected i.e. lets say
String A = "hello"
String B = "hello"
Now String B called "hello".toUpperCase() which change the same object into "TEST" , so A will also be "TEST" which is not desirable.
=====EDIT=====
If we are talking about how many string objects are there:
String s = "hello"; // one string object in the string pool "hello"
String s2 = "hello"; // two object variables (s, s2)
in this simple case, "abc" will go in the pool and s and s2 will refer to it.
String s3 = new String("hello"); // creates two objects, and one reference variable.
In this case, because we used the new keyword, Java will create a new String object
in a normal (nonpool) memory and s will refer to it. In addition the literal "hello"
will be placed in the pool as well (if it doesn't exist).
.equals() method matches two strings based on values (contents present) in that String and == check whether two objects points to same reference or not.
check the link below you will get your answer,
difference between == and equals method
use String.contentEquals:
"stringA".contentEquals("StringB");
Strings are objects, and whenever you create a 'new string' it actually creates a 'new String(value)' which points to a location in memory For example a "float" is a primitive/value, whereas Float is an Object with a pointer to a location in memory. When you use '==' it simply checks if the pointers are the same. "String.contentEquals" checks to see if the contents of both objects are the same.
Related
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 6 years ago.
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
if (s1 == s2) is giving true
while (s3 == s4) is giving false.
Can somebody give a detailed explanation onto what is String pool, heap, how many objects are created in each line and how many objects created in total.
Why s3==s4 is giving false?
A detailed explanation will be much appreciated.
When you do new String(...), it is evaluated at runtime and hence creates two different instances and you end up getting s3 == s4 as false. Same thing happens when you use StringBuilder and do something like sb.toString() which is again evaluated at runtime.
For Example,
StringBuilder sb = new StringBuilder();
String foo = sb.append("abc").toString();
String bar = new String("abc");
String foobar = "abc";
Here foo, bar and foobar are all different objects and hence foo == bar or foo == foobar will evaluate to false.
On the other hand s1 == s2 returns true because abc one declared, already exists in the String Pool and in this case both the objects points to the same reference in the pool.
String Class in java is defined in java.lang package and it is exactly that, a class and not a primitive like int or boolean.
Strings are developed to offer operations with many characters ans are commmonly used in almost all the Java applications
Some interesting facts about Java and Strings:
String in immutable and final in Java and in this case JVM uses String Pool to store all the String objects.
What are different ways to create String Object?
We can create String object using new operator like any normal java class or we can use double quotes (literal assignment) to create a String object.
There are too several constructors available in String class to get String from char array, byte array, StringBuffer and StringBuilderetc etc.
To your Question:
When we create a String using double quotes, JVM looks in the String pool to find if any other String is stored with same value. If found, it just returns the reference to that String object else it creates a new String object with given value and stores it in the String pool.
When we use new operator, JVM creates the String object but don’t store it into the String Pool. We can use intern() method to store the String object into String pool or return the reference if there is already a String with equal value present in the pool.
So when you do
String s1 = "abc";
String s2 = "abc";
those are checked in the StringPool and since s1 already exist there, s2 will take the same reference, hence, s1 ==s2 is true.
but when you do:
String s3 = new String("abc");
String s4 = new String("abc");
you are using the new operator, therefore the JVM is not checking if there is an string already in the heap, it will just allocate a new space for s4, so is s3==s4 ??? of course no.
Please take a look at the image below for a more illustrative example.
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I have the following code:
public class Porow{
public static void main (String[] args){
String s1 = "foo";
String s2 = "foo";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
String s3 = new String ("foo");
System.out.println(s1 == s3);
System.out.println(s1.equals(s3));
}
}
which outputs:
true
true
false
true
I am trying to understand and explain what's going on here. And I need some guidance. Will I be right to say s1 and s2 are same objects stored in different parts of memory and that's why we get the first 2 trues?
Why is the 3rd output false? is s3 a different object? and why does it produce true with the equals method on s1? I'd appreciate some help. Thanks :).
EDIT:
This question is not about == nor equals() I know what they are. My question is more related to memory references and addresses. So don't just presume I'm asking about String Comparison. I'm asking about a whole different thing here.
That's because in the 3rd scenario, a new object is created(the new keyword creates a new string object) and == is used for object reference equality. That's why it returns false.
Whereas the equals() method is used for String value equality, and hence, it returns true.
In the first and second case, the "foo" String literal is interned and thus, both s1 and s2 refer the same String literal.
The == operator checks reference equivalence. If the two references are equivalent, then they're the same instance.
Your first example works because the strings are interned - but don't rely on this. equals() actually checks to see if the two Strings contain the same data.
With the new keyword, a new reference is created for the other string - hence, they no longer point to the same instance.
Because == tests that the strings refer to the same object and equals tests if they are equivalent. Your line
String s3 = new String ("foo");
constructs a new reference to the constant "foo" String. Take a look at What is String interning? for a bit more, but be aware that interning will use PermGen space.
String are put into a String pool
When you have
String s1 = "foo";
String s2 = "foo";
Only one "foo" is placed into the String pool.
So
s1 == s2 is true becuase they reference the Same String "foo" in the pool
To answer your question, your assumptions are right!
The last true s1.equals(s3) compares the value "foo", that's why they are equal.
So just remember with Strings
== compares Object reference
equals compares value.
So my question is in relation to declaring and assigning strings.
The way I usually declare strings is by doing the following:
String s1 = "Stackoverflow";
And then if I ever need to change the value of s1 I would do the following:
s1 = "new value";
Today I found another way of doing it and declaring a string would go like:
String s2 = new String("Stackoverflow");
And then changing the value would be:
s2 = new String("new value");
My question is what is the difference between the two or is it simply preferential. From looking at the code the fourth line
s2 = new String ("new value");
I'm assuming that doing that would create a new memory location and s2 would then point to it so I doubt it would be used to change the value but I can see it being used when declaring a string.
From the javadoc :
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.
So no, you have no reason not to use the simple literal.
Simply do
String s1 = "Stackoverflow";
Historically, this constructor was mainly used to get a lighter copy of a string obtained by splitting a bigger one (see this question). Now, There's no normal reason to use it.
String s1 = "Stackoverflow"; // declaring & initializing s1
String s2 = new String("Stackoverflow"); // declaring & initializing s2
in above cases you are declaring & initializing String object.
The difference between
//first case
String s2 = new String("new String"); // declaring & initializing s2 with new memory
// second case
s2 = "new String" // overwriting previous value of s2
is in the first case you are creating a new object, i-e; allocating memory for a new object which will be refrenced by s2. The previous address to which s2 was pointing/referencing hasn't released the memory yet which will be gc when the program ends or when system needs to.
The good programming practice (second case) is to initialize an object once, and if you want to change its value either assign null to it and then allocate new memory to it or in case of string you can do like this
s2= "new String";
String s1 = "Stackoverflow";
This line will create a new object in the String pool if it does not exist already. That means first it will first try searching for "Stackoverflow" in the String pool, if found then s1 will start pointing to it, if not found then it will create a new object and s1 will refer to it.
String s2 = new String("Stackoverflow");
Will always create a new String object, no matter if the value already exists in the String pool. So the object in the heap would then have the value "Stackovrflow" and s2 will start pointing to it.
s2 = new String("new value");
This will again create a new Object and s2 will start pointing to it. The earlier object that s2 was pointing to is not open for garbage collection (gc).
Let me know if this helps.
The main difference is that the constructor always creates a totally new instance of String containing the same characters than the original String.
String s1 = "Stackoverflow";
String s2 = "Stackoverflow";
Then s1 == s2 will return true
String s1 = "Stackoverflow";
String s2 = new String("Stackoverflow");
Then s1 == s2 will return false
Just using the double quotes option is often better:
With a constructors you might create two instance of String.
Easier to read and less confusing
#user2612619 here i want to say is .. when ever ur creating object with "new" operator it always falls in heap memory . so wenever u have same content but different objects than also it will create new objects on heap by this u cant save memory ....
but in order to save memory java people brought concept of immutable where we can save memory .. if u r creating a different object with same content .. string will recognize dat difference and creates only one object with same content and points the two references to only one object ..
i can solve ur doubts from this figure ..
case 1:
String s = new String("stackoverflow");
String s1 = new String("stackoverflow");
as they are two different objects on heap memory with two different values of hashcode .. so s==s1 (is reference comparison) it is false .. but s.equals(s1) is content comparison ..so it is true
case 2:
String s = "stackoverflow";
String s1 = "stackoverflow";
here objects fall in scp(string constant pool memory)
same object for two different refernces .. so hashcode also same .. same reference value .. so s==s1 is true here [u can observe from figure clearly]
s.equals(s1) is true as content comparison.. this is very beautiful concept .. u will love it wen u solve some problems ... all d best
Creating String object Directly:
String s1 = "Hip Hop"
will create a string object but first JVM checks the String constant or literal pool and if the string does not exist, it creates a new String object “Hip jop” and a reference is maintained in the pool. The variable s1 also refers the same object. Now, if we put a statement after this:
String s2 = "Hip Hop"
JVM checks the String constant pool first and since the string already exists, a reference to the pooled instance is returned to s2.
System.out.println(s1==s2) // comparing reference and it will print true
java can make this optimization since strings are immutable and can be shared without fear of data corruption.
Creating String Object using new
String s3 = new String("Hip Hop")
For new keyword, a String object is created in the heap memory wither or not an equal string object already exists in the pool and s3 will refer to the newly created one.
System.out.println(s3==s2) // two reference is different, will print false
String objects created with the new operator do not refer to objects in the string pool but can be made to using String’s intern() method. The java.lang.String.intern() returns an interned String, that is, one that has an entry in the global String literal pool. If the String is not already in the global String literal pool, then it will be added to the pool.
String s4 = s3.intern();
Systen.out.println(s4 == s2); // will print `true` because s4 is interned,
//it now have the same reference to "Hip Hop" as s2 or s1
But try:
Systen.out.println(s4 == s3) // it will be false,
As the reference of s4, s2 and s1 is the reference to the pooled instance while s3 is referring to the created object in heap memory.
use of new for creting string:
prior to OpenJDK 7, Update 6, Java String.susbtring method had potential memory leak. substring method would build a new String object keeping a reference to the whole char array, to avoid copying it. You could thus inadvertently keep a reference to a very big character array with just a one character string. If we want to have minimal strings after substring, we use the constructor taking another string :
String s2 = new String(s1.substring(0,1));
The issue is resolved in JDK 7 update 6. So No need to create string with new any more for taking advantage provided by String literal pool mechanism.
Referance:
String literal pool
using new to prevent memory leak for using substring
This question already has answers here:
What is the difference between "text" and new String("text")?
(13 answers)
Closed 6 years ago.
If I declare a String as
String test=new String("testing");
and
String test1="testing1"
Since String is a class in JAVA how does test1 be a String Object without using a new Operator.Also,when a new Operator is used memory is assigned for new String("testing") so in the case of test1 how is the memory assigned?
Also,when the string is interned ,if two Strings have the same value with what reference is the String store once in the String intern pool?
Let us first consider this String test=new String("testing");
It creates an String Object in Heap.No Checking is done in String Pool for existence of this String in the pool.
and now this String test1="testing1"
It creates String a String Object in String Pool not in Heap.Before Creation check is done whether this string is already there in the pool.If yes its reference is returned else a new String is created in the pool and its reference is returned.Basically this is a String Literal, which is put in Constant pool for memory optimization and re-usability.
intern(): It is used when you construct an object using new() and you call intern() on that object then first a check is done in Stirng pool if that String already exists there or not,if yes it is directly used
Java has a separate memory for Strings that are created without calling the constructor with new. Every time such a String is created Java checks if that String is already in this memory. If it is, then Java sets the same reference to the new String until one of them changes.
When you create a String with the constructor using new then it behaves as a normal object in Java.
Take a look at this example:
String s1 = "Test";
String s2 = "Test";
When you compare this String with the == operator it will return true. s1.equals(s2) will also return true.
It looks different if you create String objects with the constructor like this:
String s1 = new String("Test");
String s2 = new String("Test");
When you now compare this Strings with the == operator it will return false, because the reference of this strings is now different (you created 2 unique String objects).
But if you use s1.equals(s2) it will return true as expected.
When you are using
String test1="testing1"
then it means you are storing only one copy of each distinct string value
but
String test=new String("testing");
gives you a new string object.
Consider your second assignment was:
String1 test1 = System.getenv("PATH");
Here, test1 is most probably also a reference to a String object, without using new().
You can assign references to already existing objects to new variables.
So where is the problem?
The problem is, you must not use sloppy wording like "test1 is a String object". It is not. It is a reference to a String object or null. That's all about it.
The code below should not print "Bye", since == operator is used to compare references, but oddly enough, "Bye" is still printed. Why does this happen? I'm using Netbeans 6.9.1 as the IDE.
public class Test {
public static void main(String [] args) {
String test ="Hi";
if(test=="Hi"){
System.out.println("Bye");
}
}
}
This behavior is because of interning. The behavior is described in the docs for String#intern (including why it's showing up in your code even though you never call String#intern):
A pool of strings, initially empty, is maintained privately by the class String.
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.
It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.
All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification.
So for example:
public class Test {
private String s1 = "Hi";
public static void main(String [] args) {
new Test().test();
System.exit(0);
}
public void test() {
String s2 ="Hi";
String s3;
System.out.println("[statics] s2 == s1? " + (s2 == s1));
s3 = "H" + part2();
System.out.println("[before interning] s3 == s1? " + (s3 == s1));
s3 = s3.intern();
System.out.println("[after interning] s3 == s1? " + (s3 == s1));
System.exit(0);
}
protected String part2() {
return "i";
}
}
Output:
[statics] s2 == s1? true
[before interning] s3 == s1? false
[after interning] s3 == s1? true
Walking through that:
The literal assigned to s1 is automatically interned, so s1 ends up referring to a string in the pool.
The literal assigned to s2 is also auto-interned, and so s2 ends up pointing to the same instance s1 points to. This is fine even though the two bits of code may be completely unknown to each other, because Java's String instances are immutable. You can't change them. You can use methods like toLowerCase to get back a new string with changes, but the original you called toLowerCase (etc.) on remains unchanged. So they can safely be shared amongst unrelated code.
We create a new String instance via a runtime operation. Even though the new instance has the same sequence of characters as the interned one, it's a separate instance. The runtime doesn't intern dynamically-created strings automatically, because there's a cost involved: The work of finding the string in the pool. (Whereas when compiling, the compiler can take that cost onto itself.) So now we have two instances, the one s1 and s2 point to, and the one s3 points to. So the code shows that s3 != s1.
Then we explicitly intern s3. Perhaps it's a large string we're planning to hold onto for a long time, and we think it's likely that it's going to be duplicated in other places. So we accept the work of interning it in return for the potential memory savings. Since interning by definition means we may get back a new reference, we assign the result back to s3.
And we can see that indeed, s3 now points to the same instance s1 and s2 point to.
Hard-coded Strings are compiled into the JVM's String Table, which holds unique Strings - that is the compiler stores only one copy of "Hi", so you are comparing that same object, so == works.
If you actually create a new String using the constructor, like new String("Hi"), you will get a different object.
There is a String cache in java. Where as in this case the same object is returned from the cache which hold the same reference.
The main reason for that is because the "Hi" is picked up from String Pool. The immutable object must have some sort of cache so it can perform better. So String class is immutable and it uses String Pool for basic cache.
In this case, "Hi" is in the String pool and all the String having values of "Hi" will have the same reference for String Pool.