java string with new operator and a literal - java

Suppose we create a String s as below
String s = new String("Java");
so this above declaration will create a new object as the new operator is encountered.
Suppose in the same program if we declare a new String s1 as below :
String s1 = "Java";
Will this create a new object or will it point to the old object with Java as it is already created with new operator above.

Well, the second line won't create a new object, because you've already used the same string constant in the first line - but s1 and s will still refer to different objects.
The reason the second line won't create a new object is that string constant are pooled - if you use the same string constant multiple times, they're all resolved to the same string. There still has to be a String object allocated at some point, of course - but there'll only be one object for all uses. For example, consider this code:
int x = 0;
for (int i = 0; i < 1000000; i++) {
String text = "Foo";
x += text.length();
}
This will not create a million strings - the value of text will be the same on every iteration of the loop, referring to the same object each time.
But if you deliberately create a new String, that will definitely create a new object - just based on the data in the existing one. So for example:
String a = new String("test");
String b = new String("test");
String x = "test";
String y = "test";
// Deliberately using == rather than equals, to check reference equality
System.out.println(a == b); // false
System.out.println(a == x); // false
System.out.println(x == y); // true
Or to put it another way, the first four lines above are broadly equivalent to:
String literal = "test";
String a = new String(literal);
String b = new String(literal);
String x = literal;
String y = literal;

String myString = new String("Java");
creates two objects.
String myString = "Java";
creates one object.

In order to create a new object we use new keyword, Object cannot be created without using new.
As per the declaration in the first instance a new Object is created but in the second instance you are only declaring a variable with a value.
So its not an Object.

String s1="foo"; literal will be created in StringPool.
String s2="foo"; this time it will check "foo" literal is already available in StringPool or not as now it exist so s2 will refer the same literal as s1.
String s3=new String("foo"); "foo" literal will be created in StringPool first then through string arg constructor String Object will be created i.e "foo" in the heap due to object creation through new operator then s3 will refer it.

When you create a String with literal (e.g. String str = "Hello";) the Object is not created in Heap it will be available in StringPool only, however when you create a String using 'new' operator (e.g. String str = new String("Hello")) then the Object in StringPool is created along with one more object in Heap. So we are creating two objects unnecessarily. So string creating with literal is preferred way.

Related

Confusion about new String and String literals in Java

According to Kathy Sierra's book:
String s = "abc"; // creates one String object and one
// reference variable
In this simple case, "abc" will go in the pool and s will refer to it.
String s = new String("abc"); // creates two objects,
// and one reference variable
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,the literal "abc" will be placed in the pool.
As I know, when we use literals, it stores value in pool but when we use new keyword it creates object in heap. Here I want to know, is the heap object refer pool data (String) or not?
The variable you created using new String("abc") is not the same as the pool "abc" string.
String string1 = "abc";
String string2 = new String("abc");
System.out.println(string1.equals(string2)); //will print true
System.out.println(string1 == string2); //will print false

what happens with new String("") in String Constant pool

if i create a string object as
String s=new String("Stackoverflow");
will String object created only in heap, or it also makes a copy in String constant pool.
Thanks in advance.
You only get a string into the constant pool if you call intern or use a string literal, as far as I'm aware.
Any time you call new String(...) you just get a regular new String object, regardless of which constructor overload you call.
In your case you're also ensuring that there is a string with contents "Stackoverflow" in the constant pool, by the fact that you're using the string literal at all - but that won't add another one if it's already there. So to split it up:
String x = "Stackoverflow"; // May or may not introduce a new string to the pool
String y = new String(x); // Just creates a regular object
Additionally, the result of a call to new String(...) will always be a different reference to all previous references - unlike the use of a string literal. For example:
String a = "Stackoverflow";
String b = "Stackoverflow";
String x = new String(a);
String y = new String(a);
System.out.println(a == b); // true due to constant pooling
System.out.println(x == y); // false; different objects
Finally, the exact timing of when a string is added to the constant pool has never been clear to me, nor has it mattered to me. I would guess it might be on class load (all the string constants used by that class, loaded immediately) but it could potentially be on a per-method basis. It's possible to find out for one particular implementation using intern(), but it's never been terribly important to me :)
In this case you are constructing an entirely new String object and that object won't be shared in the constant pool. Note though that in order to construct your new String() object you actually passed into it a String constant. That String constant is in the constants pool, however the string you created through new does not point to the same one, even though they have the same value.
If you did String s = "Stackoverflow" then s would contain a reference to the instance in the pool, also there are methods to let you add Strings to the pool after they have been created.
The new String is created in the heap, and NOT in the string pool.
If you want a newly create String to be in the string pool you need to intern() it; i.e.
String s = new String("Stackoverflow").intern();
... except of course that will return the string literal object that you started with!!
String s1 = "Stackoverflow";
String s2 = new String(s1);
String s3 = s2.intern();
System.out.println("s1 == s2 is " + (s1 == s2));
System.out.println("s2 == s3 is " + (s2 == s3));
System.out.println("s1 == s3 is " + (s1 == s3));
should print
s1 == s2 is false
s2 == s3 is false
s1 == s3 is true
And to be pedantic, the String in s is not the String that was created by the new String("StackOverflow") expression. What intern() does is to lookup the its target object in the string pool. If there is already a String in the pool that is equal(Object) to the object being looked up, that is what is returned as the result. In this case, we can guarantee that there will already be an object in the string pool; i.e. the String object that represents the value of the literal.
A regular java object will be created in the heap, and will have a reference s type of String. And, there will be String literal in String Constant Pool. Both are two different things.
My answer is YES!
Check the following code first:
String s0 = "Stackoverflow";
String s1 = new String("Stackoverflow");
String s2 = s1.intern();
System.out.println(s0 == s1);
System.out.println(s1 == s2 );
System.out.println(s0 == s2);
//OUTPUT:
false
false
true
s0 hold a reference in the string pool, while new String(String original) will always construct a new instance. intern() method of String will return a reference in the string pool with the same value.
Now go back to your question:
Will String object created only in heap, or it also makes a copy in String constant pool?
Since you already wrote a string constant "Stackoverflow" and pass it to your String constructor, so in my opinion, it has the same semantic as:
String s0 = "Stackoverflow";
String s1 = new String(s0);
which means there will be a copy in String constant pool when the code is evaluated.
But, if you construct the String object with following code:
String s = new String("StackoverflowSOMETHINGELSE".toCharArray(),0,13);
there won't be a copy of "Stackoverflow" in constant pool.

What's the difference between return (string expr) and return New String(string expr)?

Is there a difference between these two methods?
public String toString() {
return this.from.toString() + this.to.toString();
}
public String toString() {
return new String(this.from.toString() + this.to.toString());
}
(assuming, of course, that the from.toString() and to.toString() methods are returning Strings).
Basically I'm confused about String handling in Java, because sometimes strings are treated like a primitive type even though they are class instances.
There is no difference in real.
as both of your function has return type String, creating a new String() is just a overhead. it like wrapping a string to again to a string and create a new string in pool which in real has no advantage.
But one major difference in primitive type and String object is that class String always create new string.
String str = "my string";
if "my string" already exists in String pool. then it will use the same string instead of creating new.
This is the reason why when,
String str1= "my string";
String str2 ="my string";
str1==str2? --> will return true
The result of above will be true, because same String object from pool is used.
but when you do,
String str = new String("new string");
Always, a new String object is created, irrespective of a same one already exists in pool or not.
so comparing:
String str1 = new String("new string");
String str2 = new String("new string");
str1==str2 --> will return false
There is a difference, if at some point you previously defined a String "ABC". Java interns strings, so when you don't explicitly state that you want a new object, it will return an object that has the same value. So for example.
String abc = "abc";
// Some code.
return new String("abc"); // This will be a new object.
Whereas if you do this:
String abc = "abc";
// Some code.
return "abc"; // This will be the above object.
This is because it's pointless for the JVM to waste memory with objects of the same value, so it stores them in memory and waits for you to need / use them again!
Which one do you go for?
More often than not the String interning process won't hamper you too much, so you're usually okay going for the former.
The second one has an extra overhead.. In the second method you are initializing the string one more time that the first one ... something like
String s = "something";
return s;
vs
return new(s);
apart from that both will do the exact same task.
return new String(this.from.toString() + this.to.toString());
Above statement will create 2 objects.
1st object is referring to concatenated value of this.from.toString() + this.to.toString(). This doesn't have reference.
2nd object is created because of new operator.
return this.from.toString() + this.to.toString();
This will create 1 object on heap memory area.

How many String objects will be created here?

String x = new String("xyz");
String y = "abc";
x = x + y;
How many String objects would get created in this code?
There will be at least four objects:
The interned string "xyz"
The copy of the interned "xyz" string
The interned string "abc"
The result of concatenating the two strings.
String x = new String("xyz");
There's one: "xyz" is an interned string.
There's two: new String("xyz").
String y = "abc";
There's three: "abc" is an interned string.
x = x + y;
There's four. Since strings are immutable a third string object must be created: new String("xyzabc").
It's possible there could be a fifth object, because the compiler could use a StringBuilder to perform string concatenation.
StringBuilder s = new StringBuilder(x);
s.append(y);
x = s.toString();
When the class is loaded, two String objects are created (most likely), one for each String literal. This is a one-time thing ...
Each time the code is run, two Strings are created:
The new String("xyz") creates a new String whose state is the same as the "xyz" literal.
The String concatenation x + y creates a second new String.
It should be noted that String y = "abc"; does NOT create a new String. Rather, it assigns the reference to an existing String to y. In fact, it is the reference to the String object for the literal that was created when the class was loaded.
Actually, if you drill down, there is going to be a char[] array created for each of the String objects created. And the String concatenation may involve the creation of a temporary StringBuilder object. Both of these are implementation details.
It is also possible that loading the class might not result in creation of new String objects. It is true that the String literals will be represented by String Objects in the string pool, however the exact process of how that happens is an implementation detail ... and it doesn't necessarily entail calling String.intern on a freshly created String object.
And yet another answer is that ZERO objects get created. That is just Java source code, and Java source code doesn't create objects unless you compile it and run it. (Tada!!)
x : as you are using the new keyword and constructor of the class String a String object is created
"abc": is a string literal and Java creates a String object whenever it encounters a string literal.
x : the concatenation of two strings is transformed to StringBuilder.append(X).append(Y).toString(), so another object is created here.

Diff bet new String("xyz") and "xyz" in Java [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
difference between string object and string literal
Hello,
Foremost, let’s come up with Java facts with String
Strings are immutable
My Question - If Strings are immutable then below statement should have compilation error!
String str = "xyz";
or
String str = new String("xyz");
str = "abc"; //COMPILATION ERROR
or
str = new String("abc"); //COMPILATION ERROR
What is the difference between below instantiation ?
String str = "xyz";
and
String str = new String("xyz");
Amit.
Strings are immutable means you can't do something like str[1] = 'x' i.e you cannot change the content of the string.
This will answer your second question.
Strings are immutable, so you cannot change the contents of a string.
In the following code:
String str = "xyz";
str = "abc";
you're not changing the contents of a String instance, but rather assigning a new String instance to the variable str. That is, if you do:
String str = "xyz";
String otherStr = str;
String str = "abc";
Then otherStr will remain the same. So you're not actually changing the object that str points to.
As for your second question
String str = "xyz";
takes the a String-object with value "xyz" from the String pool, while
String str = new String("xyz");
instantiates a new object.
That is, if you do
String a = "xyz", b = "xyz";
you will have a == b, while if you do
String a = new String("xyz"), b = new String("xyz");
this will not be the case.example
For more information, see:
What is String literal pool?
Questions about Java's String pool
Strings are immutable. String references are not. That's the distinction.
So:
String str = "abc";
str is a variable, referring to an immutable string "abc". Now if I do:
str = "def";
str is still a variable, referring to a different immutable string ("def"). I can change what str points to all I want, str is a variable. I can't change the actual content of any string (because Java's strings are immutable, by design). Whenever you do something that would seem to modify the string (say, toUpperCase), what it's actually doing is creating a new string with a copy of the old string's contents, modified in the way described.
The point of having strings be immutable is that I know that if I have a reference to a string, that string can never change. This is a very useful guarantee when passing strings around. If we didn't have this guarantee, we'd be copying strings all the time just to protect ourselves from someone modifying them. For instance, consider a standard setter function for a name property:
void setName(String n) {
this.name = n;
}
If strings weren't immutable, we'd have to do this:
void setName(String n) {
this.name = new String(n); // Blech, duplication
}
...so that we know our copy of the string won't change in ways we don't expect it to. This would result in a lot of duplication of string data in memory, most of it unnecessary, and so the designers of Java quite intelligently decided that strings would be immutable, and any changes you might want would create a new string rather than modifying the old one in-place. (You can get modify-in-place behavior for those situations that really warrant it by using char[] instead.)
Regarding your separate question about the difference between str = "abc"; and str = new String("abc"), the difference is that the latter (using the constructor) is guaranteed to return a new reference, whereas the former is not. E.g.:
String a = "abc";
String b = "abc";
String c = new String("abc");
a == b (checking whether the references match, not the strings) will be true, because literal strings are interned. a == c is guaranteed to be false, because we used the constructor for c. a.equals(b) and a.equals(c) will both be true, because a, b, and c all refer to equivalent strings.
If Strings are immutable then below
statement should have compilation
error!
You are misunderstanding the immutability concept. Look at Prasoon's answer.
String immutability means you cannot alter the contents inside the string.
String a = "hello";
String b = "hello";
System.out.println(a==b); // returns true.
Here both a and b both string literals refer the same object.
What is the difference between two
instantiations ?
String a = "hello";
String b = "hello";
System.out.println(a==b); // returns true.
Both refer to same String literal.
String a = new String("hello");
String b = new String("hello");
System.out.println(a==b); // returns false.
Two different String Objects are created.
String str = "xyz";
is an internal cached string instance.
String str = new String("xyz");
is a new object not instanciated from the cache
As side fact notice the following behaviour ...
"xyz" == "xyz" evals true
new String("xyz") == new String("xyz") evals false
new String("xyz").equals(new String("xyz")) evals true
notice also that == in Java compares object references.

Categories