I learned about the Java String Pool recently, and there's a few things that I don't quiet understand.
When using the assignment operator, a new String will be created in the String Pool if it doesn't exist there already.
String a = "foo"; // Creates a new string in the String Pool
String b = "foo"; // Refers to the already existing string in the String Pool
When using the String constructor, I understand that regardless of the String Pool's state, a new string will be created in the heap, outside of the String Pool.
String c = new String("foo"); // Creates a new string in the heap
I read somewhere that even when using the constructor, the String Pool is being used. It will insert the string into the String Pool and into the heap.
String d = new String("bar"); // Creates a new string in the String Pool and in the heap
I didn't find any further information about this, but I would like to know if that's true.
If that is indeed true, then - why? Why does java create this duplicate string? It seems completely redundant to me since the strings in java are immutable.
Another thing that I would like to know is how the .intern() function of the String class works: Does it just return a pointer to the string in the String Pool?
And finally, in the following code:
String s = new String("Hello");
s = s.intern();
Will the garbage collector delete the string that is outside the String Pool from the heap?
You wrote
String c = new String("foo"); // Creates a new string in the heap
I read somewhere that even when using the constructor, the String Pool is being used. It
will insert the string into the String Pool and into the heap.
That’s somewhat correct, but you have to read the code correctly. Your code contains two String instances. First, you have the string literal "foo" that evaluates to a String instance, the one that will be inserted into the pool. Then, you are creating a new String instance explicitly, using new String(…) calling the String(String) constructor. Since the explicitly created object can’t have the same identity as an object that existed prior to its creation, two String instances must exist.
Why does java create this duplicate string? It seems completely redundant to me since the strings in java are immutable.
Well it does so, because you told it so. In theory, this construction could get optimized, skipping the intermediate step that you can’t perceive anyway. But the first assumption for a program’s behavior should be that it does precisely what you have written.
You could ask why there’s a constructor that allows such a pointless operation. In fact, this has been asked before and this answer addresses this. In short, it’s mostly a historical design mistake, but this constructor has been used in practice for other technical reasons; some do not apply anymore. Still, it can’t be removed without breaking compatibility.
String s = new String("Hello");
s = s.intern();
Will the garbage collector delete the string that is outside the String Pool from the heap?
Since the intern() call will evaluate to the instance that had been created for "Hello" and is distinct from the instance created via new String(…), the latter will definitely be unreachable after the second assignment to s. Of course, this doesn’t say whether the garbage collector will reclaim the string’s memory only that it is allowed to do so. But keep in mind that the majority of the heap occupation will be the array that holds the character data, which will be shared between the two string instances (unless you use a very outdated JVM). This array will still be in use as long as either of the two strings is in use. Recent JVMs even have the String Deduplication feature that may cause other strings of the same contents in the JVM use this array (to allow collection of their formerly used array). So the lifetime of the array is entirely unpredictable.
Q: I read somewhere that even when using the constructor, the String Pool is being used. It will insert the string into the String Pool and into the heap. [] I didn't find any further information about this, but I would like to know if that's true.
It is NOT true. A string created with new is not placed in the string pool ... unless something explicitly calls intern() on it.
Q: Why does java create this duplicate string?
Because the JLS specifies that every new generates a new object. It would be counter-intuitive if it didn't (IMO).
The fact that it is nearly always a bad idea to use new String(String) is not a good reason to make new behave differently in this case. The real answer is that programmers should learn not to write that ... except in the extremely rare cases that that it is necessary to do that.
Q: Another thing that I would like to know is how the intern() function of the String class works: Does it just return a pointer to the string in the String Pool?
The intern method always returns a pointer to a string in the string pool. That string may or may not be the string you called intern() or.
There have been different ways that the string pool was implemented.
In the original scheme, interned strings were held in a special heap call the PermGen heap. In that scheme, if the string you were interning was not already in the pool, then a new string would be allocated in PermGen space, and the intern method would return that.
In the current scheme, interned strings are held in the normal heap, and the string pool is just a (private) data structure. When the string being interned a not in the pool, it is simply linked into the data structure. A new string does not need to be allocated.
Q: Will the garbage collector delete the string that is outside the String Pool from the heap?
The rule is the same for all Java objects, no matter how they were created, and irrespective of where (in which "space" or "heap" in the JVM) they reside.
If an object is not reachable from the running application, then it is eligible for deletion by the garbage collector.
That doesn't mean that an unreachable object will be be garbage collected in any particular run of the GC. (Or indeed ever ... in some circumstances.)
The above rule equally applies to the String objects that correspond to string literals. If it ever becomes possible that a literal can never be used again, then it may be garbage collected.
That doesn't normally happen. The JVM keeps a hidden references to each string literal object in a private data structure associated with the class that defined it. Since classes normally exists for the lifetime of the JVM, their string literal objects remain reachable. (Which makes sense ... since the application may need to use them.)
However, if a class is loaded using a dynamically created classloader, and that classloader becomes unreachable, then so will all of its classes. So it is actually possible for a string literal object to become unreachable. If it does, it may be garbage collected.
I got a doubt while trying with the string class.
I came to know that string is immutable in java and even if we are performing any string operation to the current string, it will create a new string object. For example, if I apply trim() to the current string object then it will create new object. So my question is then what happens to the old string object. Whether it is removed from the heap replacing with the new object or in the other case it will keep on creating string garbage if I am performing a lot of string functions. Please clarify me?
You seem to have a misconception. When you invoke a string operation, what happens is that you get a new string with the results of that operation. Nothing happens to the old string.
For example
String strWithSpaces = " Dog ";
String strWithoutSpaces = strWithSpaces.trim();
Now you have two separate strings. One that has spaces before and after the word "Dog", and one that doesn't.
You may ask what happens if I do
String strWithSpaces = " Dog ";
strWithSpaces.trim();
Well, besically, that creates a new string without the spaces before and after "Dog", but that new string is not assigned to anything, so it is immediately eligible for garbage collection, and the old string, with the spaces, stays the same as it was.
And if I do
String strWithSpaces = " Dog ";
strWithSpaces = strWithSpaces.trim();
Again, there are two strings. But now, the new string is assigned to the same variable as the old one. So you have a reference to the new, and you can use it, but you don't have a direct reference to the old. If it wasn't created from a literal string, it would be garbage-collected.
Whether it is removed from the heap replacing with the new object or in the other case it will keep on creating string garbage if I am performing a lot of string functions.
No object is ever "replacing" another object on the heap. They all get created in a new location. Anyone who happens to still reference the "old" object can continue to use it.
So, yes, you will be producing "string garbage". But you have the garbage collector to take care of that: It removes unused objects in the background (reclaiming their memory to be re-used by future objects). If you happen to do a lot of string operations in a tight loop, consider using a StringBuilder or a char[] instead. Those exist precisely to avoid the overhead of creating lots of intermediate objects.
Based on my understanding on String objects, that every string literal is being added/created on the String Constant Pool.
String a = new String("hello world");
two objects are being created, one is the "hello world" being added on the constant pool and the other object is the new instance of String. Does the same principle is being applied when it comes to StringBuilder?
StringBuilder b = new StringBuilder("java is fun");
b.append(" and good");
in the StringBuilder example does it mean that there are 3 objects being created? The first one is the new instance of StringBuilder and the other 2 objects are the string literals "java is fun" and " and good"?
Yes, your understanding is correct. (But see below.) String literals go in the constant pool, while the new String(...) and new StringBuilder(...) create additional objects. (The StringBuilder also creates an internal character array object, so that there are at least four objects involved in the second example.) Note that the call to b.append(...) may internally create another object and some garbage, but only if the internal character array used by b needs to expand.
EDIT: As #fdreger points out in a comment, the string objects corresponding to the string literals are created not at run time, but rather at the time the class is created during the creation and loading phase of the class life cycle (as described in the Java Language Specification; see also the section on the runtime constant pool).
Yes, you're right.
"java is fun" and " and good" are going to be stored in the constant pool. I would call them objects, but yes, it's more like it.
b in this case is going to be an object with a limited lifespan. It may actually store its own copy of both strings in its buffer to work with, so that originals won't be modified.
The strings are created when the class is loaded, not when the actual code is executed. You may think of them as part of your code, exactly as any other literal value.
So in your second example:
two strings are created when the code is loaded for the first time
no strings are created during the execution of the code.
Now I know this question is asked a lot of times, and has been answered many times, but still someone new to Java will find the explanation tough to understand.
So what I have understood from these question is as follows
String a = "hi";
The above statement first checks whether the string is present in string pool. If not, it adds it in the pool and a reference of it is created in the pool. Basically the object is made in permanent generation area and string pool is used to have a reference of it.
However, with
String a = new String("hello");
In this case, it creates two object. One in permanent generation area, and one in the normal heap memory. The a contains a reference to the heap memory object.
Now my question is whether this concept is right or not. Does string pool is references or a pool of actual strings and whether the concept of permanent generation area here I understood is right or not? If wrong please explain in layman's language. Please don't make it duplicate, as I already know this has been answered a lot of times. None was in layman's language and easy to understand. Are two objects actually made? If yes, then how, and if no, then why? It would be really helpful.
The effect of what you say is basically correct. The problem with your formulation concerns when things happen. When you write
String a="hi";
or indeed, your Java file has the string literal "hi" anywhere in it, then this string literal is allocated only once: when the class is loaded, when your code starts running. Then the initialization of a just uses the existing String object. But when you have an explicit constructor call as in
String a=new String("hi");
then a new String is created. new means a new string object.
Yes, you understand it well. When you do:
String a = new String("hello");
There will be 2 created Strings, one on the pool and one object, not in the pool that contains a copy of the content that's stored in the object from the pool.
You'll have something like that:
Pool
+-------+
|"hello" <-------- a
| |
+-------+
String a= new String("hello")
one object in string pool is created and one another object is created by new operator in heap area.and a is holding the reference of String pool object and string pool object is holding the reference of heap object. and heap object contains hello.
What exactly does immutable mean - that is, what are the consequences of an object being mutable or immutable? In particular, why are Java's Strings immutable?
My understanding is that the StringBuilder type is something like a mutable equivalent to String. When would I use StringBuilder rather than String, and vice-versa?
Immutable means that once the constructor for an object has completed execution that instance can't be altered.
This is useful as it means you can pass references to the object around, without worrying that someone else is going to change its contents. Especially when dealing with concurrency, there are no locking issues with objects that never change
e.g.
class Foo
{
private final String myvar;
public Foo(final String initialValue)
{
this.myvar = initialValue;
}
public String getValue()
{
return this.myvar;
}
}
Foo doesn't have to worry that the caller to getValue() might change the text in the string.
If you imagine a similar class to Foo, but with a StringBuilder rather than a String as a member, you can see that a caller to getValue() would be able to alter the StringBuilder attribute of a Foo instance.
Also beware of the different kinds of immutability you might find: Eric Lippert wrote a blog article about this. Basically you can have objects whose interface is immutable but behind the scenes actual mutables private state (and therefore can't be shared safely between threads).
An immutable object is an object where the internal fields (or at least, all the internal fields that affect its external behavior) cannot be changed.
There are a lot of advantages to immutable strings:
Performance: Take the following operation:
String substring = fullstring.substring(x,y);
The underlying C for the substring() method is probably something like this:
// Assume string is stored like this:
struct String { char* characters; unsigned int length; };
// Passing pointers because Java is pass-by-reference
struct String* substring(struct String* in, unsigned int begin, unsigned int end)
{
struct String* out = malloc(sizeof(struct String));
out->characters = in->characters + begin;
out->length = end - begin;
return out;
}
Note that none of the characters have to be copied! If the String object were mutable (the characters could change later) then you would have to copy all the characters, otherwise changes to characters in the substring would be reflected in the other string later.
Concurrency: If the internal structure of an immutable object is valid, it will always be valid. There's no chance that different threads can create an invalid state within that object. Hence, immutable objects are Thread Safe.
Garbage collection: It's much easier for the garbage collector to make logical decisions about immutable objects.
However, there are also downsides to immutability:
Performance: Wait, I thought you said performance was an upside of immutability! Well, it is sometimes, but not always. Take the following code:
foo = foo.substring(0,4) + "a" + foo.substring(5); // foo is a String
bar.replace(4,5,"a"); // bar is a StringBuilder
The two lines both replace the fourth character with the letter "a". Not only is the second piece of code more readable, it's faster. Look at how you would have to do the underlying code for foo. The substrings are easy, but now because there's already a character at space five and something else might be referencing foo, you can't just change it; you have to copy the whole string (of course some of this functionality is abstracted into functions in the real underlying C, but the point here is to show the code that gets executed all in one place).
struct String* concatenate(struct String* first, struct String* second)
{
struct String* new = malloc(sizeof(struct String));
new->length = first->length + second->length;
new->characters = malloc(new->length);
int i;
for(i = 0; i < first->length; i++)
new->characters[i] = first->characters[i];
for(; i - first->length < second->length; i++)
new->characters[i] = second->characters[i - first->length];
return new;
}
// The code that executes
struct String* astring;
char a = 'a';
astring->characters = &a;
astring->length = 1;
foo = concatenate(concatenate(slice(foo,0,4),astring),slice(foo,5,foo->length));
Note that concatenate gets called twice meaning that the entire string has to be looped through! Compare this to the C code for the bar operation:
bar->characters[4] = 'a';
The mutable string operation is obviously much faster.
In Conclusion: In most cases, you want an immutable string. But if you need to do a lot of appending and inserting into a string, you need the mutability for speed. If you want the concurrency safety and garbage collection benefits with it the key is to keep your mutable objects local to a method:
// This will have awful performance if you don't use mutable strings
String join(String[] strings, String separator)
{
StringBuilder mutable;
boolean first = true;
for(int i = 0; i < strings.length; i++)
{
if(first) first = false;
else mutable.append(separator);
mutable.append(strings[i]);
}
return mutable.toString();
}
Since the mutable object is a local reference, you don't have to worry about concurrency safety (only one thread ever touches it). And since it isn't referenced anywhere else, it is only allocated on the stack, so it is deallocated as soon as the function call is finished (you don't have to worry about garbage collection). And you get all the performance benefits of both mutability and immutability.
Actually String is not immutable if you use the wikipedia definition suggested above.
String's state does change post construction. Take a look at the hashcode() method. String caches the hashcode value in a local field but does not calculate it until the first call of hashcode(). This lazy evaluation of hashcode places String in an interesting position as an immutable object whose state changes, but it cannot be observed to have changed without using reflection.
So maybe the definition of immutable should be an object that cannot be observed to have changed.
If the state changes in an immutable object after it has been created but no-one can see it (without reflection) is the object still immutable?
Immutable objects are objects that can't be changed programmatically. They're especially good for multi-threaded environments or other environments where more than one process is able to alter (mutate) the values in an object.
Just to clarify, however, StringBuilder is actually a mutable object, not an immutable one. A regular java String is immutable (meaning that once it's been created you cannot change the underlying string without changing the object).
For example, let's say that I have a class called ColoredString that has a String value and a String color:
public class ColoredString {
private String color;
private String string;
public ColoredString(String color, String string) {
this.color = color;
this.string = string;
}
public String getColor() { return this.color; }
public String getString() { return this.string; }
public void setColor(String newColor) {
this.color = newColor;
}
}
In this example, the ColoredString is said to be mutable because you can change (mutate) one of its key properties without creating a new ColoredString class. The reason why this may be bad is, for example, let's say you have a GUI application which has multiple threads and you are using ColoredStrings to print data to the window. If you have an instance of ColoredString which was created as
new ColoredString("Blue", "This is a blue string!");
Then you would expect the string to always be "Blue". If another thread, however, got ahold of this instance and called
blueString.setColor("Red");
You would suddenly, and probably unexpectedly, now have a "Red" string when you wanted a "Blue" one. Because of this, immutable objects are almost always preferred when passing instances of objects around. When you have a case where mutable objects are really necessary, then you would typically guard the objet by only passing copies out from your specific field of control.
To recap, in Java, java.lang.String is an immutable object (it cannot be changed once it's created) and java.lang.StringBuilder is a mutable object because it can be changed without creating a new instance.
In large applications its common for string literals to occupy large bits of memory. So to efficiently handle the memory, the JVM allocates an area called "String constant pool".(Note that in memory even an unreferenced String carries around a char[], an int for its length, and another for its hashCode. For a number, by contrast, a maximum of eight immediate bytes is required)
When complier comes across a String literal it checks the pool to see if there is an identical literal already present. And if one is found, the reference to the new literal is directed to the existing String, and no new 'String literal object' is created(the existing String simply gets an additional reference).
Hence : String mutability saves memory...
But when any of the variables change value, Actually - it's only their reference that's changed, not the value in memory(hence it will not affect the other variables referencing it) as seen below....
String s1 = "Old string";
//s1 variable, refers to string in memory
reference | MEMORY |
variables | |
[s1] --------------->| "Old String" |
String s2 = s1;
//s2 refers to same string as s1
| |
[s1] --------------->| "Old String" |
[s2] ------------------------^
s1 = "New String";
//s1 deletes reference to old string and points to the newly created one
[s1] -----|--------->| "New String" |
| | |
|~~~~~~~~~X| "Old String" |
[s2] ------------------------^
The original string 'in memory' didn't change, but the
reference variable was changed so that it refers to the new string.
And if we didn't have s2, "Old String" would still be in the memory but
we'll not be able to access it...
"immutable" means you cannot change value. If you have an instance of String class, any method you call which seems to modify the value, will actually create another String.
String foo = "Hello";
foo.substring(3);
<-- foo here still has the same value "Hello"
To preserve changes you should do something like this
foo = foo.sustring(3);
Immutable vs mutable can be funny when you work with collections. Think about what will happen if you use mutable object as a key for map and then change the value (tip: think about equals and hashCode).
java.time
It might be a bit late but in order to understand what an immutable object is, consider the following example from the new Java 8 Date and Time API (java.time). As you probably know all date objects from Java 8 are immutable so in the following example
LocalDate date = LocalDate.of(2014, 3, 18);
date.plusYears(2);
System.out.println(date);
Output:
2014-03-18
This prints the same year as the initial date because the plusYears(2) returns a new object so the old date is still unchanged because it's an immutable object. Once created you cannot further modify it and the date variable still points to it.
So, that code example should capture and use the new object instantiated and returned by that call to plusYears.
LocalDate date = LocalDate.of(2014, 3, 18);
LocalDate dateAfterTwoYears = date.plusYears(2);
date.toString()… 2014-03-18
dateAfterTwoYears.toString()… 2016-03-18
I really like the explaination from SCJP Sun Certified Programmer for Java 5 Study Guide.
To make Java more memory efficient, the JVM sets aside a special area of memory called the "String constant pool." When the compiler encounters a String literal, it checks the pool to see if an identical String already exists. If a match is found, the reference to the new literal is directed to the existing String, and no new String literal object is created.
Objects which are immutable can not have their state changed after they have been created.
There are three main reasons to use immutable objects whenever you can, all of which will help to reduce the number of bugs you introduce in your code:
It is much easier to reason about how your program works when you know that an object's state cannot be changed by another method
Immutable objects are automatically thread safe (assuming they are published safely) so will never be the cause of those hard-to-pin-down multithreading bugs
Immutable objects will always have the same Hash code, so they can be used as the keys in a HashMap (or similar). If the hash code of an element in a hash table was to change, the table entry would then effectively be lost, since attempts to find it in the table would end up looking in the wrong place. This is the main reason that String objects are immutable - they are frequently used as HashMap keys.
There are also some other optimisations you might be able to make in code when you know that the state of an object is immutable - caching the calculated hash, for example - but these are optimisations and therefore not nearly so interesting.
One meaning has to do with how the value is stored in the computer, For a .Net string for example, it means that the string in memory cannot be changed, When you think you're changing it, you are in fact creating a new string in memory and pointing the existing variable (which is just a pointer to the actual collection of characters somewhere else) to the new string.
String s1="Hi";
String s2=s1;
s1="Bye";
System.out.println(s2); //Hi (if String was mutable output would be: Bye)
System.out.println(s1); //Bye
s1="Hi" : an object s1 was created with "Hi" value in it.
s2=s1 : an object s2 is created with reference to s1 object.
s1="Bye" : the previous s1 object's value doesn't change because s1 has String type and String type is an immutable type, instead compiler create a new String object with "Bye" value and s1 referenced to it. here when we print s2 value, the result will be "Hi" not "Bye" because s2 referenced to previous s1 object which had "Hi" value.
Immutable means that once the object is created, non of its members will change. String is immutable since you can not change its content.
For example:
String s1 = " abc ";
String s2 = s1.trim();
In the code above, the string s1 did not change, another object (s2) was created using s1.
Immutable simply mean unchangeable or unmodifiable. Once string object is created its data or state can't be changed
Consider bellow example,
class Testimmutablestring{
public static void main(String args[]){
String s="Future";
s.concat(" World");//concat() method appends the string at the end
System.out.println(s);//will print Future because strings are immutable objects
}
}
Let's get idea considering bellow diagram,
In this diagram, you can see new object created as "Future World". But not change "Future".Because String is immutable. s, still refer to "Future". If you need to call "Future World",
String s="Future";
s=s.concat(" World");
System.out.println(s);//print Future World
Why are string objects immutable in java?
Because Java uses the concept of string literal. Suppose there are 5 reference variables, all refers to one object "Future".If one reference variable changes the value of the object, it will be affected to all the reference variables. That is why string objects are immutable in java.
Once instanciated, cannot be altered. Consider a class that an instance of might be used as the key for a hashtable or similar. Check out Java best practices.
As the accepted answer doesn't answer all the questions. I'm forced to give an answer after 11 years and 6 months.
Can somebody clarify what is meant by immutable?
Hope you meant immutable object (because we could think about immutable reference).
An object is immutable: iff once created, they always represent the same value (doesn't have any method that change the value).
Why is a String immutable?
Respect the above definition which could be checked by looking into the Sting.java source code.
What are the advantages/disadvantages of the immutable objects?
immutable types are :
safer from bugs.
easier to understand.
and more ready for change.
Why should a mutable object such as StringBuilder be preferred over String and vice-verse?
Narrowing the question Why do we need the mutable StringBuilder in programming?
A common use for it is to concatenate a large number of strings together, like this:
String s = "";
for (int i = 0; i < n; ++i) {
s = s + n;
}
Using immutable strings, this makes a lot of temporary copies — the first number of the string ("0") is actually copied n times in the course of building up the final string, the second number is copied n-1 times, and so on. It actually costs O(n2) time just to do all that copying, even though we only concatenated n elements.
StringBuilder is designed to minimize this copying. It uses a simple but clever internal data structure to avoid doing any copying at all until the very end, when you ask for the final String with a toString() call:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; ++i) {
sb.append(String.valueOf(n));
}
String s = sb.toString();
Getting good performance is one reason why we use mutable objects. Another is convenient sharing: two parts of your program can communicate more conveniently by sharing a common mutable data structure.
More could be found here : https://web.mit.edu/6.005/www/fa15/classes/09-immutability/#useful_immutable_types
Immutable Objects
An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.
Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.
Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a new object as opposed to updating an object in place. The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated with immutable objects. These include decreased overhead due to garbage collection, and the elimination of code needed to protect mutable objects from corruption.
The following subsections take a class whose instances are mutable and derives a class with immutable instances from it. In so doing, they give general rules for this kind of conversion and demonstrate some of the advantages of immutable objects.
Source
An immutable object is the one you cannot modify after you create it. A typical example are string literals.
A D programming language, which becomes increasingly popular, has a notion of "immutability" through "invariant" keyword. Check this Dr.Dobb's article about it - http://dobbscodetalk.com/index.php?option=com_myblog&show=Invariant-Strings.html&Itemid=29 . It explains the problem perfectly.