Can we able to access the object in String pool which is does not not have any reference.
Here is code :
String str ="abc";
str.toUpperCase();
System.out.println(str); // System.out.println(str.toUpperCase());
Output : abc
Here I am performing the toUpperCase() operation on str. In String pool one object will be created for this str.toUpperCase();. Can we able to access this object.? if yes how?
This is where java documentation is used .... Refer http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#toUpperCase()
str.toUpperCase() returns a string converted to upper case, you have to assign it to another string variable or do a self assignment, so you can access it later.
String str ="abc"; // 1
str.toUpperCase(); // 2
System.out.println(str); // 3
in above code
First line will create new Object of String with value "abc" and assign it to the reference variable str.
Second line will create the new Object of String because String class is immutable so original Object str will not change. but here we are not assigning the new object which is created in line 2 so it will be lost somewhere in Heap area.
That is why in line 3 printing value is "abc".
if you want to use the new Object created by str.toUpperCase() than have to assign that in a new reference variable.
or
alternative option is update the original String Object like this
str = str.toUpperCase();
but in above operation, the original Object str containing the value "abc" will be lost in the Heap area !!!!!
You can find details about working with String by example here.
Related
My textbook says a String is not over-writable or immutable, i.e, once you enter the value of a String you can't change it. But today when I was running the following code, the String str gets muted as the compiler does not give any error and the new String a's value is successfully entered into str.
class Test
{
static void main()
{
String str = "something";
String a ="anything";
str = a; //str is being over written without any error
System.out.println(str);
}
}
The output is : anything
So, is my book wrong ?
If my book is not wrong please give an example to show that Strings are immutable
The book is correct. When you say str = a you are not changing anything about the String 'something'. You should distinguish between str and something, they are not the same. "something" here is a String object in memory, whereas str is just the reference to that string. Same with the reference a.
When you say:
str = a
You are not changing something, you are in fact saying, "change the reference str to point to whatever the reference a is pointing to." The Strings remain the same, the references change.
On a similar note, this is why you may see in your book that concatenating Strings is expensive, as doing something like:
str = str + a
Would again not be changing the existing Strings, but instead creating a new String object which is equal to the concatenation of the String that the reference str is referring to and the String that the reference a is referring to.
You need to understand what immutable means. In your scenario you are just changing references.
str = a;
will make both a and str to point to String "anything". The Text Book is correct. String is immutable and can not be overwritten. If you check the JavaDoc for String. Most of the methods return a String. This is because any operation in a String will not change that String object but will result in a new String being created. Effectively you can never change a String after you create it. By Change I mean append new characters, remove characters without a new String object being created.
As many answers already point out is that you only change references. Immutable means you cannot change the string itself. for example you do:
String a = "anything";
System.out.println(a); // -> anything
a.substring(3);
System.out.println(a); // -> anything : this is because the String itself is
// immutable.
a = a.substring(3);
System.out.println(a); // -> thing : this is what immutable means to edit a string
// you must reassign it or assign it
// to a new variable
You're changing the reference of str to a. So str effectively becomes a's value.
they are just pointer to that string. so when you do str =a , you just assign pointer of a to str.
The contents of the String object is not being changed. What's happening is that a new String object is being assigned to the variable. The old String object still exists in memory but you just can't refer to it any more. The 'str' variable now refers to the String object containing "anything" but the String containing "something" still exists as it did before. Try assigning 'str' to another variable first and then, after assigning 'a' to 'str', check that other variable and you'll see that it still says "something", proving that that String was not overwritten.
In Java, the value of a variable is never an object, but a reference. Relevant to your case, the type String on the a variable says the variable is allowed to contain only references to String objects.
You can update the value in the variable, sure; but that won't touch the object it is referring to.
Strings are constant; their values cannot be changed after they are created.
The String object is created and stored on constant pool or literal pool.
In your case, when you say,
String str="something"; // An object is created on constant pool with value 'something' and reference 'str' is pointing to it.
String a="anything"; // An object is created on constant pool with value 'anything' and reference 'a' is pointing to it.
And when you do, str=a; then 'str' actually start pointed to 'a', but the object with value as 'something' remains on constant pool with the same value.
I have a question concerning establishing String objects in Java.
Let's say I create a String object like this:
String mystring=new String();
Now, if I take this String object and assign to it a string like this:
mystring="abc";
What exactly happened here? Is mystring addressed exactly to the original object or is it a different object? Like String mystring; is the short-hand for String mystring=new String(); what could mystring="abc"; stand for?
String mystring = new String();
creates a new String object and assigns the value of its reference to the variable mystring.
So
Variable Heap
-------- ----
mytring ---------------------> "" // an empty String object
Then you do
mystring="abc";
This assigns the value of the reference to the String object "abc" to the variable mystring. So
Variable Heap
-------- ----
mystring -------------------> "abc"
"" // will be garbage collected at some point
A variable does not change. The object it's referencing or the reference itself can change.
Like String mystring; is the short-term for String mystring=new
String();
No String mystring; is a variable declaration. When that line is executed, the variable mystring is declared but not initialized.
On the other hand, String mystring = new String() both declares and initializes the variable mystring.
for what could mystring="abc"; stand for?
That is an assignment expression, assigning the value of the reference to the String object "abc" to the variable mystring.
It's also important to understand that Strings are immutable. Once you create a String object, you cannot change it. For example, in the following code
String name = "user3133542"; // cool
name = "some other value";
You are not changing the object that name is referencing, you are creating a new object and assigning its value to the variable name.
The String API does not provide any methods to change its value. We therefore call it immutable.
Consider going through the Java String tutorial.
Also, before you ask your next question, read this
How do I compare strings in Java?
You are changing mystring with mystring="abc"; It is not the exactly to the original object at all. The mystring is a variable not object.
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
i have basic confusion .
String s2=new String("immutable");
System.out.println(s2.replace("able","ability"));
s2.replace("able", "abled");
System.out.println(s2);
In first print statement it is printing immutability but it is immutable right? why so?
and
in next printing statement it is not replaced> any answers welcome..
System.out.println(s2.replace("able","ability"));
In above line, A new string returned and printed.
Because String#replce()
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
s2.replace("able", "abled");
It does the replace operation but,not assigned the result back.So the original String remains the same.
You see the result if you assign the result.
like
String replacedString = s2.replace("able", "abled");
System.out.println(replacedString );
or
s2= s2.replace("able", "abled");
System.out.println(s2);
Update:
When you write line
System.out.println(s2.replace("able","ability"));
That s2.replace("able","ability") resolved and returned String passed to that function.
The replace(String,String) method returns a new String. The second call to replace() returns the replacement but you don't assign it to anything, then when you print out the immutable s2 again, you see the unchanged value.
String#replace returns the resulting String without modifying the original (immutable) String value...
You will get the same result if you assign the result to another String, for example
String s2=new String("immutable");
String s3 = s2.replace("able","ability");
System.out.println(s3);
s2.replace("able", "abled");
System.out.println(s2);
Will give you the same out put...
Lets look at line - 2:
System.out.println(s2.replace("able","ability"));
This will print immutability, this is because
s2.replace("able","ability")
will return another string, which is fed like:
System.out.println(tempStr);
But in third statement,
s2.replace("able", "abled");
There is no assignment to another variable, so a string is returned but not assigned to any variable. Hence lost, but s2 remain as is.
Immutable objects are simply objects whose state (the object's data) cannot change after construction
Your code s2.replace("able","ability"), it return a new String and nothing happen for s2.
And because replace function return a new String, so you can print the result by System.out.println(s2.replace("able","ability"));
String is Immutable, but String have a lot of methods that you can use as Rvalue
See also:
Immutable objects
RValue
String#replace
String s2=new String("immutable");
1)When ever we create a String as above a new object is created.If we are trying to modify it, a new object is created with the content we are providing and our String s2 is not modified.
2)If we need the modified value in the s2 object then replace the above code as..
String s2=new String("immutable");//Creates a new object with content 'immutable'
System.out.println(s2.replace("able","ability"));//creates a new object with new content as //immutability
s2=s2.replace("able", "abled");//Here also it creates a new object,Since we are assigning it //to s2,s2 will be pointing to newly created object.
System.out.println(s2);//prints the s2 String value.
I have refernced the following links
What is String pool in Java?
Garbage collection and Strings
http://www.xyzws.com/Javafaq/what-is-string-literal-pool/3
Questions about Java's String pool
Still have some doubts please help me
`public class StrPool
{
public static void main(String[] args)
{
String abc="hello";
String abcd="hello";
System.out.println(abc==abcd);
}
}
`
In the above example OP : true
So we can confirm that both object are refered from same String object Am clear about that.
`String abc="hello World";
String abcd="hello";
System.out.println(abc==abcd);`
This gives output : false
So String pool is carried out when two String object having same literal???
If So two object of String will created in String pool??
Why second output is false ???
I READ THAT String class is immutable
abc and abcd have different object reference then Immutable means
" First String object will created by JVM and give two reference to abc and abcd " Am i right???
Thank you very much........
The second output is false as both the string abc and abcd having different content(text)
yes as you said String class is immutable ie their content does not gets changed, if in case you change the string text then JVM will allocate a new space instead of altering it.
Now when you create a new String reference with some text at that time JVM will check if that text already exists in pool and if then will refer your string to that text or else will create new text within pool
Java automatically applies String.intern to double quoted literals. Thus it is guaranteed that
String foo1 = "foo";
String foo2 = "foo";
assert foo1 == foo2;
However, for strings constructed other than as literals this is not guaranteed, i.e. given
String foo1 = "foo";
// contrived example, but imagine foo2 came from reading a file or similar
String foo2 = new String(new char[] { 'f', 'o', 'o' });
it is guaranteed that foo1.equals(foo2) but not necessarily that foo1 == foo2. You can call intern explicitly - it is guaranteed that foo1 == foo2.intern() - but it's generally clearer to use equals when you care about value equality and only use == when you really need reference equality.
Consider first code,
While executing statement String abc="hello", JVM will do following things
1. create a reference abc of type String.
2. check if literal "hello" is available in string pool
if available, it will assign its reference value to abc,
else it will create string literal "hello", assign its reference to abc and add it to String pool.
Same step will be repeated for String abcd="hello". Here, as "hello" is already available in string pool, same will be referred by abcd.
These same steps will be followed in second code block as well, (in fact everytime you create string object with such statement) just that the literal "hello world" and "hello" will be created differently and assigned to their respective variables.
I guess, now you can guess the reason behind the output of above two code samples.
String is immutable, means that you can not change any string object. Instead JVM will create new string object (or fetch one from string pool) and assign it to the reference.
e.g.
String varA = "hello"; -> 1
String varB = "hello"; -> 2
varA="world" -> 3
varB ="world" -> 4
At line 1, JVM will create String object "hello" in string pool and assign its reference to varA.
At line 2, JVM will assign the reference of "hello" object already present in String pool to varB.
At line 3, JVM will create a new object "world" and assign its reference to varA. Now String pool will have two objects , "hello" and "world".
At line 4, JVM will assign the reference of "world" object already present in String pool to varB. String pool will still have two objects , "hello" and "world".
So basically, JVM has not modified any String object, it has just modified the reference.
Hope it helps you. If you have any problem please comment.
So String pool is carried out when two String object having same literal???
--> Not exactly, String pool is carried out when you define literal string. If you create literal string object like String obj = "sometext" and While creating second literal like String obj1 = "some Other Text", obj1 contents will be compared to "sometext" by JVM. If both contents are equal like String str1 = "hello" and String str2 = "hello", then object references str1 and str2 will be pointed to same object("hello").
Why second output is false ???
--> because abc and abcd points to different string objects.
Immutable means: once object is created you can not change its contents.