This question already has answers here:
How many objects are being created? [duplicate]
(2 answers)
Closed 9 years ago.
How many string objects will be created by the following code?
String s="";
s+=new String("a");
s+="b";
I had this question at exam. I want to know the right answer . I said 2 objects.
The object from pool that contains "" , "b" and the object created by new String("a");
I'll anwser to another, clearer question: how many String instances are involved in the following code snippet:
String s="";
s+=new String("a");
s+="b";
And the answer is 6:
the empty String literal: "";
the String literal "a";
the copy of the String literal "a": new String("a");
the String created by concatenating s and the copy of "a";
the String literal "b"
the String created by concatenating s and "b".
If you assume that the three String literals have already been created by previously-loaded code, the code snippet thus creates 3 new String instances.
String s="";
creates no objects.
s+=new String("a");
creates five objects. the new String, the StringBuilder and its char[] and the String resulting and its char[]
s+="b";
creates four objects, the StringBuilder and its char[] and the String resulting and its char[]
So I get a total of nine objects of which are three String objects
Note: You can be sure that "" has already been loaded as it appear in many system classes including ClassLoader and Class.
The Strings "a" and "b" may or may not be considered as new Strings for the purpose of this question. IMHO I wouldn't count them as they will only be created at most once and if this code is only run once, it hardly matters how many strings are created. What is more likely to be useful is to know how many objects are created each time the code is run.
The number of objects actually created in a JITC situation is indeterminate. The JITC may well recognize that new String("a") is an identity, and that no intermediate values of s are referenced, so that only the StringBuilder is created. There are several potential side-effects that must be mimicked in the general case (eg, where the argument to new String() may be invalid), but with literals they can't occur.
In fact, javac could very well recognize that the result is "ab", with no potential side-effects, and just produce a String literal of that value. (It does string combining in slightly less complicated cases.)
Creating New Strings
Earlier we promised to talk more about the subtle differences between the various methods of creating a String. Let's look at a couple of examples of how a String might be created, and let's further assume that no other String objects exist in the pool:
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.
From SCJP Sun Certified Programmer for Java 6 Study Guide (Exam 310-065).pdf
Related
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I was looking into the String API and suddenly I came across one String empty Constructor i.e. we can construct an empty String object using String s = new String()
I wonder is there any use of it?
Ofcourse.....
String s = new String();
will create a Non-literal String object on the heap, which will be garbage collected.
where as
String s = "" ;
will create a String Literal. This will not be garbage collected ever, if it is reachable through the default loader.
See this link below to a question which I asked. This may not be directly related to your question, but it will certainly help you grasp the concept firmly.
Is String Literal Pool a collection of references to the String Object, Or a collection of Objects
It creates the empty string, which appears to have some limited use.
If you'll be building up a String by concatenating, and aren't using e.g. StringBuiler, your code can begin as one of the following.
String result = new String();
String result = "";
String result = "first part of string";
// ...
result += "append to the result";
The first two aren't equivalent, and you should prefer to initialize with "" since this can take advantage of string interning.
Small example... String can be garbage collected
System.out.println(1 + new String() + 2);
instead of
System.out.println(1 + "" + 2);
According to the documentation, this constructor creates an empty sequence.
public String()
Initializes a newly created String object so that it represents an empty character sequence. Note that use of this constructor is unnecessary since Strings are immutable.
If you want an empty sequence, it makes sense.
But normally, it wouldn't be necessary to use the empty constructor before you make changes to it, since you are not changing the String. In fact, when you change using the operator += for example, you are creating another immutable String, and not changing one.
Check this question about this subject: How do String objects work (like immutable objects)?
Some background first
Because Strings in Java are immutable, they are also "interned" - that means that all the string literals in the loaded classes are kept in a pool, so there is usually only one instance of each unique string literal in memory at one time. It is an application of the flyweight pattern, similar pools are also kept for Integer and other primitive wrapper objects (but only for a limited number of small values).
Because of this mechanism, identity comparison of string literals (even from different classes) is usually possible (although you should always use equals method when comparing strings for safety and consistency):
System.out.println("hello" == "hello"); // true
Now, if you use the default string constructor, you get an instance of an empty string, but it is a new instance, as stated in JavaDoc:
Initializes a newly created String object so that it represents an empty character sequence. Note that use of this constructor is unnecessary since Strings are immutable.
Such new instance is different from the interned empty string, resulting in:
System.out.println(new String() == ""); // false
But as I said, only string literals are automatically interned - that means strings created manually by StringBuilders, from char arrays etc. are not interned. You can use the String.intern() method to put such a string into the pool manually.
Now for some real scenario
Well all this is nice indeed, but I still haven't answered why this constructor exists. Well, Java strings are just smart wrappers over char arrays and some distinct string objects can share their internal arrays.
If I create a very long string (by reading from a stream for example), then this instance isn't interned (as said above), so it will be garbage collected after the variable that referenced it gets out of scope. But if do this:
String longString = readVeryLongString();
String shortString = longString.subString(0, 10);
... then the new shortString will not copy first 10 characters from the longString and put them into its own new char array. No, it will reference the original array, using only first 10 chars from it.
Now, if the shortString variable has longer life (for example is put into some static context), then the underlying char array will not be garbage collected (even if the original longString variable already got out of scope). This is one of the ways how to create a memory leak in Java.
Now, the default string constructor comes to the rescue! If I change the code above to this:
String longString = readVeryLongString();
String shortString = new String(longString.subString(0, 10));
... then the shortString will be a new string instance that made a new internal char array by copying only the 10 required chars from the original string returned by the subString method.
A nice article illustrating this subject:
http://illya-keeplearning.blogspot.cz/2009/03/java-string-internals.html
to create an empty string,call default constructor as
String s new String();
will create an instance of String with no characters in it.
This question already has answers here:
String s = new String("xyz"). How many objects has been made after this line of code execute?
(21 answers)
Closed 7 years ago.
I was going through SCJP examination and found one line in one book.
String s = new String("abc");
And it was written that, two objects will be created on above line. one on HEAP and one on STRING POOL.
I am not satisfied by the declaration given there. Can someone make me understand why two objects are created ?
Thanks in advance.
Author is correct. When ever you used String literal, that literal goes to constant pool first.
Hence "abc" created in constant pool.
And when you use new key word a new Object called s created on heap.
The literal "abc" is created and interned ("string pool").
The new operator will create a new String that is not interned.
Author is correct:
one object will be created in the string pool for "abc" literal; and
another object will be created on the heap for new String(...)
Object 1 - "abc"
Object 2 - new String("abc")
This question already has answers here:
What is the Java string pool and how is "s" different from new String("s")? [duplicate]
(5 answers)
Closed 7 years ago.
String s = new String("abc")
I know that this would create a new String object in Heap.
But i am confused about a statement in SCJP book by Kathy Sierra.
It states that the above statement would create an object in heap and at the same if the String "abc" is not present in the String pool , it would also add "abc" to the String pool.
Could anyone please tell me if the object "abc" is also created in the String pool in the above case.
String s = new String("abc")
Yes,above line will create two objects, one in string pool and other in Heap.
So, now
1) If you create a string literal like:-
String s1="abc"; //abc value will be taken from string pool which is previously added
2) If you create a String object and call intern method, no new object will be created instead it will just refer to "abc" present in string pool.
String s2=new String("abc").intern();
Note: When we are creating new String object based on existing one, it reuses char[] value.
Since new String(someStringValue) creates an exact copy of existing string and strings are immutable, there is clearly no reason for the two to exist at the same time.
Even if you have two String objects, they might still point to the same content.
You can refer this:- https://dzone.com/articles/string-memory-internals
Yes, it will be created as you are not having the same string before this line in your code. Now consider this example.
String temp = "abc"; // line1
String s = new String("abc"); // line2
In this case "abc" is not recreated. s will point to "abc" that was created at line 1.
sujith in comment : But in that case i do not see any difference between String temp ="abc" and String temp = new String("abc").
In line 1 a new "abc" will be created in heap. And a new String object will be created and added into the stack. And in line2 a new object of String will be created which will be referring to the "abc" that was created at line1 in heap. To better understand what thing goes to stack and what goes to heap visit here.
Yes it does. To optimize memory use, it does so.
In case you create another variable with same value "abc",
new variable will still point to earlier rather than creating a new one.
Somehow it is trying not to create two equal objects
This question already has answers here:
How many objects are created
(4 answers)
Closed 9 years ago.
In a simulation for a the OCJP certification I found this question:
1. StringBuffer s1 = new StringBuffer("abc");
2. StringBuffer s2 = s1;
3. StringBuffer s3 = new StringBuffer("abc");
How many objects are created ?
They state that the correct answer is 4 because they state:
s1 is one object, s2 is another object,
s3 is another object and "abc" is another String Object .
But for me it's wrong and it should be 3, because s1 and s2 are the same object. What do you think?
You are right that the answer is not 4 objects.
However, the question "how many objects are created" is ambiguous. The issue is that one of the three objects is not created when you execute the code. Specifically, the String object that corresponds to the "abc" literal is actually created when the code is loaded. When that code is executed, two StringBuffer objects are created, and the pre-existing String object is used.
And in fact it is more complicated than that, since at class load time it is possible that another temporary String object is created and then discarded after it has been interned;
If an "abc" literal has already been loaded in a different class, then that one will be used.
It is not specified if the string pool implementation makes a fresh copy of the String if it needs to put it into the pool.
Unless the question is more precisely stated, there is no single correct answer. The best you can say is:
Two StringBuffer objects are created when the code is run.
One or two String objects are created when the code is loaded.
Then there is the issue of whether you should count the private char[] objects that form part of the StringBuffer and String objects. That could inflate the object count to as much as 8.
Yes definitely 3 Object.both s1 and s2 referring same location. so s1, s2 and "abc" are the objects here. May be it is better not to follow that reference.
CORRECTION
There should be 3 objects:
1. StringBuffer s1 = new StringBuffer("abc");
Two objects will be created in memory s1 & "abc" . This is because, strings are interned and literals are added to a memory pool.
2. StringBuffer s2 = s1;
No object will be created here because s2 will point to "abc" created as part of s1
3. StringBuffer s3 = new StringBuffer("abc");
Only one object will be create for s3.
How about:
1. StringBuffer s1 = new StringBuffer("abc");
1 builder object + 1 char[] object + (1 String literal, if created)
2. StringBuffer s2 = s1;
No new objects.
3. StringBuffer s3 = new StringBuffer("abc");
1 builder object + 1 char[] object
A StringBuilder encapsulates the backing char[] inside, which is an object.
As #StephenC says the question is ambiguous.
3 or 4, depending on implementation. Some compilers would create only one String object for the constant "abc" and reference it as many times as necessary, and other compilers would create one object per constant. AFAIK, this has not been mandated by all the languages specification versions, and it could change again in the future.
Or more, depending on StringBuffer's implementation (which could actively create a char[] and copy the initialization String, as opposed to a lazy implementation that postpones this until the StringBuffer's contents are really changed). Again, this should not be mandated by the language. And, BTW, do arrays count as Objects for the purpose of the question? And what if a StringBuffer implementation stored information in a JNI structure? What that count as objects? I'm just trying to re-inforce my point about non-language-mandated implementation details.
A test should not ask this kind of questions unless it is about a specific implementation and/or JLS version.
What is absolutely clear is that the reason they give for their answer of 4 is completely incorrect. The assignment to s2 does not cause any new object to be created.
This question already has answers here:
Closed 13 years ago.
Duplicate
java String concatenation
I'm curious what is the difference between the two.
The way I understand the string pool is this:
This creates 3 string objects in the string pool, for 2 of those all references are lost.
String mystr = "str";
mystr += "end";
Doesn't this also create 3 objects in the string pool?
String mystr = "str";
mystr = mystr.concat("end")
I know StringBuilder and StringBuffer are much more efficient in terms of memory usage when there's lots of concatination to be done. I'm just curious if there's any difference between the + operator and concat in terms of memory usage.
There's no difference in this particular case; however, they're not the same in general.
str1 += str2 is equivalent to doing the following:
str1 = new StringBuilder().append(str1).append(str2).toString();
To prove this to yourself, just make a simple method that takes two strings and +='s the first string to the second, then examine the disassembled bytecode.
By contrast, str1.concat(str2) simply makes a new string that's the concatenation of str1 and str2, which is less expensive for a small number of concatenated strings (but will lose to the first approach with a larger number).
Additionally, if str1 is null, notice that str1.concat(str2) throws a NPE, but str1 += str2 will simply treat str1 as if it were null without throwing an exception. (That is, it yields "null" concatenated with the value of str2. If str2 were, say, "foo", you would wind up with "nullfoo".)
Update: See this StackOverflow question, which is almost identical.
The important difference between += and concat() is not performance, it's semantics. concat() will only accept a string argument, but + (or +=) will accept anything. If the non-string operand is an object, it will be converted to a string by calling toString() on it; a primitive will be converted as if by calling the appropriate method in the associated wrapper class, e.g., Integer.toString(theInt); and a null reference becomes the string "null".
Actually, I don't know why concat() even exists. People see it listed in the API docs and assume it's there for a good reason--performance being the most obvious reason. But that's a red herring; if performance is really a concern, you should be using a StringBuilder, as discussed in the thread John linked to. Otherwise, + or += is much more convenient.
EDIT: As for the issue of "creating objects in the string pool," I think you're misunderstanding what the string pool is. At run-time, the actual character sequences, "str" and "end" will be stored in a dedicated data structure, and wherever you see the literals "str" and "end" in the source code, the bytecode will really contain references to the appropriate entries in that data structure.
In fact, the string pool is populated when the classes are loaded, not when the code containing the string literals is run. That means each of your snippets only creates one object: the result of the concatenation. (There's also some object creation behind the scenes, which is a little different for each of the techniques, but the performance impact is not worth worrying about.)
The way I understand the string pool
is this:
You seem to have a misconception concerning that term. There is no such thing as a "string pool" - the way you're using it, it looks like you just mean all String object on the heap. There is a runtime constant pool which contains, among many other things, compile-time String constants and String instances returned from String.intern()
Unless the argument to concat is an empty string, then
String mystr = "str";
mystr = mystr.concat("end")
will also create 3 strings.
More info: https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html.