Well, I've got such a code
String s = "hello";
String s2 = s + "world";
I know that variable s is stored in Java Heap in String Literal Pool. Also I know that variable s2 is stored in Java Heap (because '+' in this example creates a new object). But my question is: will "world" be put into Pool or nothing will happen with it?
Yes it will. Wherever / Whenever , you have a String literal declared, it goes to pool obviously, regardless the usage of it.
Since the String "world" does not exist in the pool, a new String object instantiates, then it is placed in the pool.
When we use double quotes to create a String, it first looks for String with same value in the String pool, if found it just returns the reference else it creates a new String in the pool and then returns the reference.
Basically, 's' and 's2' are just references while real objects are "Hello" and "world". This follows the concept specifying Strings are immutable while String references are not. So, Yes, as "world" is String object,apart from being a String literal, it will be stored in heap similar to hello. Also remember neither 's' nor 's2' will goto heap as being mutable String references.
Related
This is a question that I got in an interview.
I've two strings defined as
String s1="Java";
String s2="Java";
My question is whether these two references point to the same memory location. In general, when we create identical strings (without new keyword), does the content get stored in the memory only once and all the String objects with the same content just refer to the same location, without storing the string "Java" redundantly ? The hash codes of s1 and s2 are the same. But are hashcodes dependent directly on memory location of the object?
The process of combining identical strings is called "interning", and has been done for many years by lots of language compilers, but not always. The answer to the question, especially as expanded by #GennadyVanin--Novosibirsk, depends on the language and the compiler implementation. For Java, all constant strings are interned, as required by the Java Language Specification. But that's only constant string expressions, and only when they're compiled at the same time. If you have two Java strings sufficiently separated in time and space (e.g., compiled into separate JAR files), they will not be the same object. Similarly, dynamically created Java strings (e.g., the output of various toString() methods) won't be interned unless the method specifically requests it via String.intern(). And yes, all uses of an interned string will share the same memory locations - that's a big part of why strings are interned in the first place.
As to other languages, that's a bigger question, but with all the information in these answers, I'm sure you can research it on the web. Suffice it to say that there is no universal agreement on how this ought to be done.
String s1="Java";
String s2="Java";
My question is whether these two references point to the same memory location
Dumb citing §3.10.5 of Java Language Specification:
A string literal is a reference to an instance of class String
(§4.3.1, §4.3.3).
Moreover, a string literal always refers to the same instance of class
String. This is because string literals - or, more generally, strings
that are the values of constant expressions (§15.28) - are
"interned" so as to share unique instances, using the method
String.intern.
And read the comments to code example there:
This example illustrates six points:
Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).
Literal strings within different classes in the same package represent references to the same String object.
Literal strings within different classes in different packages likewise represent references to the same String object.
Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
Strings computed by concatenation at run time are newly created and therefore distinct.
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.
When compiler optimizes your string literals, it sees that both s1 and s2 have same value and thus you need only one string object. It's safe because String is immutable in Java.
String s1="Java";
String s2="Java";
System.out.println(s1== s2);
This gives result true because s1 and s2 points to the same object.
String Pool is the mechanism that all already defined string are stored in some 'pool' and before creating new String object compiler checks if such string is already defined.
Example.
First example
String s1 = "FirstString";
String s2 = "FirstString";
if(s1 == s2) {
//This condition matched true because java don't make separate object for these two string. Both strings point to same reference.
}
Second example
String s1= "FirstString";
String s2 = new String("FirstString");
if(s1.equals(s2)) {
//This condition true because same content.
}
if(s1 == s2) {
//This condition will be false because in this java allocate separate reference for both of them
}
Conclusion: Java check whether string exist or not. If we create the object of second string using new and have different content then its creates object and assign different reference and In case of If we don't create the object using new and have same content then its assign the same reference as first string contain.
Adding to others:
new keyword always forces to create a new object.
If you declare like below:
String s1 = "some";
String s2 = "some";
Then using String Pooling mechanism, both references s1 and s2 will refer to the same String object with the value "some".
When you have
String str1 = new String("BlaBla"); //In the heap!
String str2 = new String("BlaBla"); //In the heap!
then you're explicitly creating a String object through new operator (and constructor).
In this case you'll have each object pointing to a different storage location.
But if you have:
String str1 = "BlaBla";
String str2 = "BlaBla";
then you've implicit construction.
Two strings literals share the same storage if they have the same values, this is because Java conserves the storage of the same strings! (Strings that have the same value)
String s1="Java";
String s2="Java";
both points to same object. for more detail click here
String s1="Java";
String s2="Java";
Do they point to the same memory location?
I originally said "no" but in the case above, see the StringPool answer referred to below, it's actually yes..
"when we create identical strings (without new keyword), does the
content get stored in the memory only once and all the String objects
with the same content just refer to the same location"
...kind of see detailed answer in question "Java Strings and StringPool"
"The hash codes of s1 and s2 are the same. But are hashcodes dependent
directly on memory location of the object?"
No the hashcodes depend on the content of the String
YES,
Andrew Hare was answer on stack overflow in this link https://stackoverflow.com/a/2486195/4835894.
Basically, a string intern pool allows a runtime to save memory by preserving immutable strings in a pool so that areas of the application can reuse instances of common strings instead of creating multiple instances of it.
String Str1= new String("java");
String Str3 = new String("java");
System.out.println(Str1==Str3);
The 1st line of code creates object str1 with content "java" init both in String pool and heap. Now what will Str3 does? I know it create Str3 in heap what about Str3 in String pool? What does 3rd line do? does it checks for equality in String pool or in heap area? I know that it gives false but my question is if Str1 and Str3 are stored in String pool == should give true right as references are same.
The 1st line of code creates object str1 with content "java" init both in String pool and heap.
Actually:
The string pool is part of the heap. (This doesn't actually relate to your misconception, but it helps to get these things straight in your head.)
The string object corresponding to the "java" literal is created by the classloader, not by that statement. It is created when the class is loaded1 ... not when the code is run.
So, in fact that statement only creates a string object in the heap.
Now what will Str3 does?
The second statement creates a single string object ... in the heap.
As per the above explanation, the string object for the "java" literal used in this statement was created previously. (Indeed, if you look in the bytecode file, you will see that there is only one "java" string in the file's constant pool. So, the classloader won't even need to create two string instances and intern() both of them. Only one is created and interned.)
I know it create Str3 in heap what about Str3 in String pool?
Nope. All string literals are created in the string pool, which automatically dedups them.
What does 3rd line do? Does it checks for equality in String pool or in heap area?
Nope. It tests to see if the object references are the same; i.e. if they are the same object. It doesn't actually test where they are in.
(You can't actually directly test if a String is in the pool or not. And you can't even test if an object is in the heap or not ... if the JVM provides you a way to allocate objects outside of the (regular) heap.)
I know that it gives false but my question is if Str1 and Str3 are stored in String pool == should give true right as references are same.
They aren't in the string pool. They are ordinary heap objects.
Think of it this way, the fact that == returns false proves that they aren't (both) in the string pool. Because if they were both in the string pool they would have to be the same String object.
Here is what the JLS says on string literals and identity:
"Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern."
This interning happens when the class is loaded1.
1 - The specs don't say when the interning happens. It appears that recent JVMs resolve a method's reference to a String literal lazily; i.e. the interning happens the first time the method is called by the bytecode interpreter. However, this doesn't change the substance of the above explanation.
For the below statement in a program, how many objects will be created in heap memory and in the string constant pool?
I need clarity in object creation. Many sources I've read are not elaborating. I am confused when the object gets destroyed.
String a="MAM"+"BCD"+"EFG"+"GFE";
How many objects will be created?
I am looking for good material about the life cycle of objects, methods and classes and how the JVM handles them when they are dynamically changed and modified.
"MAM"+"BCD"+"EFG"+"GFE" is a compile-time constant expression and it compiles into "MAMBCDEFGGFE" string literal. JVM will create an instance of String from this literal when loading the class containing the above code and will put this String into the string pool. Thus String a = "MAM"+"BCD"+"EFG"+"GFE"; does not create any object, see JLS 15.18.1. String Concatenation Operator +
The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).
It simply assigns a reference to String object in pool to local var a.
Only one object is created.
string s1 = "java";
string s2 = "ja" + "va";
s.o.p(s1==s2);
The statement yields true.
String s1="java";
string s2 = "ja";
String s3 = s2 +"va";
s.o.p(s1==s3);
The statement yields false.
So minimum one apparent should be permanent, then '+' operator generates new string object (in non constant pool using new()).
So, the question you asked does not have one also permanent. This means it creates only one object.
Exactly one object is created and placed in the constant pool, unless it already exists, in which case the existing object is used. The compiler concatenates string constants together, as specified in JLS 3.10.5 and 15.28.
A long string literal can always be broken up into shorter pieces and written as a (possibly parenthesized) expression using the string concatenation operator +
http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
Most answers seem to focus that a) the complete expression is one compile time constant and b) that the line itself does not construct a new object but only a reference to one object.
However noone so far has mentioned, that String itself contains a reference to an internal char[] (which is also in the constant pool).
Summary: There are two objects in the constant pool (String and char[]). The line does neither create nor destroy any object.
And regarding:
I am confused when the object gets destroyed.
No object is destroyed, since stuff in the constant pool will only be destroyed if the class itself would be unloaded. At most you can say, that the reference a will go out of scope eventually.
Only one object will be created since String a will compile into "MAMBCDEFGGFE".
Answers stating a single heap object in your example are correct. However, consider this code:
public class Tester
{
public String a="MAM";
public String b ="BCD";
public String c = "EFG";
public String d ="GFE";
public Tester()
{
String abcd = a + b + c + d;
}
}
In this example, there are 7 strings being created. a,b,c and d are not compiled into a single constant - they are members. 1 string is then created for each + operator - semantically speaking, + is a concatenation but logically it is creating a new string in memory. The first 2 operator strings are discarded immediately and are now eligible for garbage collection but the memory churn still occurs.
Technically there in an 8th object. The instance of Tester.
Edit: This has been proved to be nonsense in the comments
This is a question that I got in an interview.
I've two strings defined as
String s1="Java";
String s2="Java";
My question is whether these two references point to the same memory location. In general, when we create identical strings (without new keyword), does the content get stored in the memory only once and all the String objects with the same content just refer to the same location, without storing the string "Java" redundantly ? The hash codes of s1 and s2 are the same. But are hashcodes dependent directly on memory location of the object?
The process of combining identical strings is called "interning", and has been done for many years by lots of language compilers, but not always. The answer to the question, especially as expanded by #GennadyVanin--Novosibirsk, depends on the language and the compiler implementation. For Java, all constant strings are interned, as required by the Java Language Specification. But that's only constant string expressions, and only when they're compiled at the same time. If you have two Java strings sufficiently separated in time and space (e.g., compiled into separate JAR files), they will not be the same object. Similarly, dynamically created Java strings (e.g., the output of various toString() methods) won't be interned unless the method specifically requests it via String.intern(). And yes, all uses of an interned string will share the same memory locations - that's a big part of why strings are interned in the first place.
As to other languages, that's a bigger question, but with all the information in these answers, I'm sure you can research it on the web. Suffice it to say that there is no universal agreement on how this ought to be done.
String s1="Java";
String s2="Java";
My question is whether these two references point to the same memory location
Dumb citing §3.10.5 of Java Language Specification:
A string literal is a reference to an instance of class String
(§4.3.1, §4.3.3).
Moreover, a string literal always refers to the same instance of class
String. This is because string literals - or, more generally, strings
that are the values of constant expressions (§15.28) - are
"interned" so as to share unique instances, using the method
String.intern.
And read the comments to code example there:
This example illustrates six points:
Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).
Literal strings within different classes in the same package represent references to the same String object.
Literal strings within different classes in different packages likewise represent references to the same String object.
Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
Strings computed by concatenation at run time are newly created and therefore distinct.
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.
When compiler optimizes your string literals, it sees that both s1 and s2 have same value and thus you need only one string object. It's safe because String is immutable in Java.
String s1="Java";
String s2="Java";
System.out.println(s1== s2);
This gives result true because s1 and s2 points to the same object.
String Pool is the mechanism that all already defined string are stored in some 'pool' and before creating new String object compiler checks if such string is already defined.
Example.
First example
String s1 = "FirstString";
String s2 = "FirstString";
if(s1 == s2) {
//This condition matched true because java don't make separate object for these two string. Both strings point to same reference.
}
Second example
String s1= "FirstString";
String s2 = new String("FirstString");
if(s1.equals(s2)) {
//This condition true because same content.
}
if(s1 == s2) {
//This condition will be false because in this java allocate separate reference for both of them
}
Conclusion: Java check whether string exist or not. If we create the object of second string using new and have different content then its creates object and assign different reference and In case of If we don't create the object using new and have same content then its assign the same reference as first string contain.
Adding to others:
new keyword always forces to create a new object.
If you declare like below:
String s1 = "some";
String s2 = "some";
Then using String Pooling mechanism, both references s1 and s2 will refer to the same String object with the value "some".
When you have
String str1 = new String("BlaBla"); //In the heap!
String str2 = new String("BlaBla"); //In the heap!
then you're explicitly creating a String object through new operator (and constructor).
In this case you'll have each object pointing to a different storage location.
But if you have:
String str1 = "BlaBla";
String str2 = "BlaBla";
then you've implicit construction.
Two strings literals share the same storage if they have the same values, this is because Java conserves the storage of the same strings! (Strings that have the same value)
String s1="Java";
String s2="Java";
both points to same object. for more detail click here
String s1="Java";
String s2="Java";
Do they point to the same memory location?
I originally said "no" but in the case above, see the StringPool answer referred to below, it's actually yes..
"when we create identical strings (without new keyword), does the
content get stored in the memory only once and all the String objects
with the same content just refer to the same location"
...kind of see detailed answer in question "Java Strings and StringPool"
"The hash codes of s1 and s2 are the same. But are hashcodes dependent
directly on memory location of the object?"
No the hashcodes depend on the content of the String
YES,
Andrew Hare was answer on stack overflow in this link https://stackoverflow.com/a/2486195/4835894.
Basically, a string intern pool allows a runtime to save memory by preserving immutable strings in a pool so that areas of the application can reuse instances of common strings instead of creating multiple instances of it.
This question already has answers here:
Questions about Java's String pool [duplicate]
(7 answers)
Closed 5 years ago.
When we use new operator to create a String object, I read that two Objects are created one Object is string constant pool and second one is in heap memory.
My question here is We are using new operator hence only one object should be created in Heap. Why then one more object has to be created in String Constant pool. I know Java stores String object whenever we not use new operator to create a String. For eg:
String s = "abc" .
In this case only it will create in String constant pool.
String s2 = new String("abc")
only one object hast to be created in heap and not in Constant pool.
Please explain why I am wrong here.
We are using new operator hence only one object should be created in Heap.
Sure - the new operation only creates one object. But its parameter is a String literal, which already represents an object. Any time you use a String literal, an object was created for that during class loading (unless the same literal was already used elsewhere). This isn't skipped just because you then use the object as a parameter for a new String() operation.
And because of that, the new String() operation is unnecessary most of the time and rarely used.
See http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern
Thus when you write
String s2 = new String("abc")
The Compile-time constant expression "abc" will be interend.
It will be created two object, one object into pool area and other one in non pool area because you are using new and as well as string literal as a parameter.
String s = new String("abs");
String s2 = new String("abc")
It will create only one object in heap memory. We need to use intern() method of java.lang.String explicitly to make the entry in String pool.
String s = "def".
Two Objects will be created here. When you create using String literal notation of Java, it automatically call intern() method to put that object into String pool, provided it was not present in the pool already.
String in java is Immutable, once created its cannot be changed. also, any string literal will be stored in the string pool for later use whenever the same literal is used again, for example:
String name = "my name"; // one intern object is created in pool
String otherName = "my name"; // the old intern object is reused
System.out.println( name == otherName); // true , the same reference refer to same object
the two reference refer to the same location in the pool.
String name = new String("my name"); // one object is created, no string pool checking
String otherName = new String("my name"); // other object is created, no string pool checking
System.out.println( name == otherName); // false, we have 2 different object
here we have two different String object in memory each of them have its own value.
see this article for more:
http://www.javaranch.com/journal/200409/Journal200409.jsp#a1
form this below line of code will create 3 object in the JVM
String s2 = new String("abc")
for "abc" in String pool memory.
for new operator one object in heap.
one more for s2.
String s2 = new String("abc");
here 1 literal and 1 object will be created.
With new operator 1 String object will be created in heap as "abc" and s2 will refer it, moreover "abc" is string literal also that is passed in String Constructor so it will go in String Constant pool.
literal is consider as object so 2 object will be created here.