| Author |
counting String objects #2
|
Marlene Miller
Ranch Hand
Joined: Mar 05, 2003
Posts: 1391
|
|
When I dump the file Test.class, I see only one object �appleorangebanana�. I expected to see the three objects �apple�, �orange� and �banana� as well.
|
 |
Marlene Miller
Ranch Hand
Joined: Mar 05, 2003
Posts: 1391
|
|
I think I have figured out what is going on. In the above example, only one String object is created. In the following example 5 String objects are created. StringBuffer b = new StringBuffer(); b = b.append(�apple�); String s = new String(�orange�); b = b.append(s); b = b.append(�banana�); return b.toString(); [ May 09, 2003: Message edited by: Marlene Miller ]
|
 |
Marlene Miller
Ranch Hand
Joined: Mar 05, 2003
Posts: 1391
|
|
And in this example, 4 String objects are created. StringBuffer b = new StringBuffer(); b = b.append(�appleorange�); //1 String object String s = new String(�banana�); //2 String objects b = b.append(s); return b.toString(); //1 String object PostScript: I made a mistake. 4 String objects, not 3, are created [ May 10, 2003: Message edited by: Marlene Miller ]
|
 |
Rory French
Ranch Hand
Joined: Apr 03, 2003
Posts: 97
|
|
Hi Marlene, So I suppose these examples are a good illustration of things that can be resolved (and optimised) at compile time. Here's another code example I'd like your opinion on: How many local "String s" objects are created during a single run of this program? I have read that each thread will have its own copy of a local variable (this is the reason why synchronizing on a locally created object serves no practical purpose.). So I am curious to know if more than one copy of "String s" is created when this program runs. How can one verify this?
|
 |
Jose Botella
Ranch Hand
Joined: Jul 03, 2001
Posts: 2120
|
|
Hey, the objects are always created in the heap. The variables that point them can be created in the stack frame of a method. In this case, both threads will have method with a "s" variable pointing to the same string object. _______________________________________________ warning the following is not exam stuff, but it helps a lot! Whenever the compiler finds out the following expression: "apple" + "orange" + "banana" it replaces it with a reference to an entry in the constant pool of the class containing the expression. The content of such entry is appleorangebanana The compiler has been able to compute it because it is a compile-time constant expression (JLS 15.28) At runtime the JVM, upon the first use of the entry in the constant pool, creates a String object and replaces the content of the entry with the address of the newly created object. The String object is (first) interned. In this way all the variables referencing the former expression end up pointing the same string object.
|
SCJP2. Please Indent your code using UBB Code
|
 |
Rory French
Ranch Hand
Joined: Apr 03, 2003
Posts: 97
|
|
Aha! Good to know. Thanks Jose
|
 |
Marlene Miller
Ranch Hand
Joined: Mar 05, 2003
Posts: 1391
|
|
Thank you Jose.
it replaces it with a reference to an entry in the constant pool of the class containing the expression.
What happens when multiple classes refer to the same String literal? From these structures, it looks like each class has its own pool of String objects. But the example in JLS 3.10.5 shows that multiple classes, even in different packages, refer to the same String literal.
|
 |
Rory French
Ranch Hand
Joined: Apr 03, 2003
Posts: 97
|
|
furth ermore ... I was happy with Jose's reply to my previous question, but then the issue of synchronizing on a locally created object still bothered me, because if what Jose said is true (i.e. only one String object exists) then you should be able to successfully synchronize on it. So I did a little experiment (see code below) and discovered that this is indeed the case:
|
 |
Jose Botella
Ranch Hand
Joined: Jul 03, 2001
Posts: 2120
|
|
warningno exam stuff The constant pool of a class is not the String pool. All the String objects created from string literals or compile-time constant expressions are interned. Thus, all the references to those expressions, holding the same content, point to the same string object. The constant pool of a class using a string literal declared in another class contains entries of type CONSTANT_String_Info to those fields that are final. If the field is not final the entry is of type CONTANT_Fieldref_Info. Any way, the resolution of both types of entries must yield the same string object if the members they refer are string literals with the same content.
|
 |
Roger Chung-Wee
Ranch Hand
Joined: Sep 29, 2002
Posts: 1683
|
|
|
Rory, I think that what you have done is indeed an exception (maybe the only exception) to the rule that you should not synchronize on a local variable. The reason is that threads do not keep a local copy of s as they do for all other local variables, rather they refer to the String object in the literal pool to which they all have access.
|
SCJP 1.4, SCWCD 1.3, SCBCD 1.3
|
 |
Jose Botella
Ranch Hand
Joined: Jul 03, 2001
Posts: 2120
|
|
|
I think that each invocation of the method will spawn a local variable "s". The content of such variables is the same: the address of (the same)a String object.
|
 |
Francis Siu
Ranch Hand
Joined: Jan 04, 2003
Posts: 867
|
|
hi Jose and everybody in this thread. I get a lot the concept of creating string objects,thanks for your details description and a fews good examples to point out the problem which we confused. Warning this topic is not exam stuff, but it helps a lot!  [ May 11, 2003: Message edited by: siu chung man ]
|
Francis Siu
SCJP, MCDBA
|
 |
 |
|
|
subject: counting String objects #2
|
|
|