avn,
The String pool concept.( NOT NEEDED FOR SCJP EXAM
) We know what is a String object. It is basically a set of characters like "JavaRanch" where 'J' ,'a' , 'v' , 'a', 'R' ... and so on are all characters.
A String object created in so many ways using the many different constructors of the String class as shown here in the Java API Doc. It can be created from a byte[], char[], another String object itself, another StringBuffer object are few to name here.
All the String constructors shown in the API are used to create a String object in the heap memory using new String(....) format.
So we can further break up the diferent ways to create a String object as one of the following ways.
<pre>
1. String s1 = new String(....);
2. String s2 = "....";
3.String s3 = AStringObject+ something
(the something may be any_primitive/null/true/false/anyObject)
4. String s4 = objref.someMethod(...)
(the someMethod(..) supposed to return a String object as its return value)
</pre>
So, now we know the different ways to create a String object. Next let us see where they are created. There are 2 areas in the memory where String objects are created. They are 1.Heap 2. String pool. ( All objects created in the so called heap memory are eligible for Garbage Collection once the object loses all its references. This is just an add-on info).
A String pool is nothing but a construct which has String objects in it. The important point to note here is ALL the String objects in the String pool are created in one of the following ways.
DIFFERENT WAYS TO CREATE A STRING POOL OBJECT case 1. using " " (double quotes) String s1 = "avn"; //case 1
case 2. ADDING ALL compile time constants which are of type String final String s1 = "avn";
final String s2 = " likes";
final String s3 = " JAVARANCH";
String s4 = s1+s2+s3; //case 2
Since we know Math.PI is another compile time constant. It is static final double. The foll. also composes another String pool object
String s5 = "avn" + Math.PI;
Basically the concept is this. If there is a var whole value is CONSTANT throughout its life time, then A String object's value which is made of these vars , is also going to be constant right?. IN other words we can gurantee that the String's content is NOT going to change at all. When the compiler convinces itself that the String's content is NOT GOING to change at all ,it creates them in the String pool. But look at the following example.
String s1 ="avn";
String s2 ="likes";
String s3 ="Java";
These String references s1,s2,s3 are AT PRESENT pointing to the String objects created in the String pool "avn","likes","Java". But they CAN BE CHANGED VERY well to point to another object right? Then how can the following new String s4 can have a CONSTANT VALUE ? It is not correct right? The difference between
final String s1 = "avn"; and just
String s1="avn" is the
word 'final' which makes the ref s1 to have the CONSTANT VALUE throughout its life time.
String s4 = s1+s2+s3; //s4 is not at all a String pool object, since the individual component s1,s2,s3 are not constants.
Also just blindly remember this. Whenever a compiler sees SOMETHING between " ", it CREATES the String object in String pool. So if you take the following example, there are 3 freash String pool objects created. They are "avn","likes","Java"
String s1 ="avn"; //String pool obj1
String s2 ="likes"; //String pool obj2
String s3 ="Java"; //String pool obj3
Another point to note in case of String pool is there is ONLY ONE DISTINCT object. In other words only one "avn", only one "likes" only one "Java". If you write another set of Strings like the following in the same programme
String s1 ="avn"; //String pool obj1
String s2 ="likes"; //String pool obj2
String s3 ="Java"; //String pool obj3
String s4 ="avn"; //s4 will be = s1
String s5 ="likes"; //s5 will be = s2
String s6 ="Java"; //s6 will be = s3
now the creation of String objects s4,s5 and s6 WILL NOT create any new String pool objects. Instead s4 will point to the SAME address as that of s1, s5 will be same as s2, s6 same as s3. You get the point now. A string pool is just a pool of distinct Strings made from constant valued Strings. So now our String pool has got 3 Strings. Next assume we write the following code in our prog.
String s1 ="avn"; //String pool obj1
String s2 ="likes"; //String pool obj2
String s3 ="Java"; //String pool obj3
String s4 ="avn"; //s4 will be = s1
String s5 ="likes"; //s5 will be = s2
String s6 ="Java"; //s6 will be = s3
String s7 = "avn"+ "likes" + "java";
String s8 = "PI"+ "value=" + Math.PI;
Now our String pool has 2 newcomers who are "avnlikesJava" and "PIvalue=3.14".
At the same time even if you create another String pool object with the same content , but DIFFERENT way, in the same program, like the following
final String s9 = "PI";
final String s10 ="value="
final String s11 =s9+s10+Math.PI; // This stamement WILL NOT create a new Stirng pool object since there is ALREAY ONE in the String pool with the SAME CONTENT as "PIvalue=3.14".
Also note that all the String pool objects are created during compile time itself and the compiler has a table which has the references. So whenever the compiler sees in our code there is a possiblity to create a String pool object, then it creates it and puts the reference in its internal table. So by now our compiler table would have got 7 distinct references.
("avn","likes","java","PI","value=","avnlikesJava","Pivalue=3.14")Got it.
String pool is like a COMMON POOL of String objects, used throughout the program. But once you create a Stirng pool object it lives in memory throughout the JVM. In other words , without knowing the side effects you would have created 100 String pool objects like String name1= "111", String name2="222"...String name100="100". What really happened is there are 100 String pool objects created and there is a internal table created by the compiler which has 100 references in it and ALL these 100 objects CAN NOT be garbage collected until the JVM exits. You might have just used these objects just once or twice. But even if you set the reference to null, it WILL NOT BE garbage collected. For example,
String s1="MAHA";
s1=null; //The String pool object "MAHA" is memory is NOT GC'd.
[ ALso note that in the REAL EXAM all GC qstns are asked with String objects created in the heap which are eligible to GC once an object loses all its refs. ]
case 3. ADDING ALL String literals like "abc" +"cde"; String s5 = "avn" +" likes"+ "JavaRanch"; //case 3
case 4. calling the intern method of a String object. This is a very interesting concept. As we know there is a String class method called intern(). What it really does is , when we invoke this method on a String object, it volunteers this String object to be a common String pool object. In otherwords,
char[] charArray = {'M','A','H','A'};
String s1 = new String(charArray);
s1.intern();
What this above 3 stmnts do is a String object with content as "MAHA" is created in heap in stmnt 2. The 3rd stmnt tries to CREATE A NEW STRING POOL object whose content is same as that of s1 ref. Now what happens ?
There may be 2 cases. If there would have already existing String pool object with same content as "MAHA", then this intern() method WILL NOT create a NEW ONE as we discussed earlier. So the already existing String pool object "MAHA" 's address is returned by this method.
Another case is if there is NO PRE-EXISTING "MAHA" String pool object, then this intern() WILL CREATE a new "MAHA" String pool object and returns this new address. If you try to again call intern(), this time the JUST CREATED "MAHA" String pool object's address will be returned and NO NEW "MAHA" String pool object will be created.
So having discussed how the String pool objects are created, ALL OTHER WAYS OF creating String objects are CREATED in the heap memory.
Let us take the above 4 cases and analyze.
1. String s1 = new String(....); //obj ref'd by s1 in heap
2. String s2 = "...."; //obj ref'd by s2 in Stirng pool
3. String s3 = AStringObject + something ; //can be anywhere depending upon whether the individual comp's have constant values.
4. String s4 = objref.someMethod(...)
(can be anything depending upon what this method returns. A String pool object or heap object)
I give you some examples to explore. Consider each case as a separate code segment.
case 1: 1. String s1 = "1111";
- only one object / created in the String pool
case 2: 1. String s1 = "1111";
String s2 = "1111";
- only one object / created in the String pool by 1st stmnt / s2 ref will be SAME as s1 since maximum 1 distinct String object can be in the pool / the 2nd statement WILL NOT create a new String pool obj
case 3: 1. String s1 = "1111";
String s2 = "2222";
String s3 = "11111";
- 2 String objects / created in the String pool ("1111","2222")by 1st and 2nd stmnt / s3 = s1
case 4: 1. String s1 = "1111";
String s2 = "2222";
String s3 = "1111"+"2222";
- 3 String objects / created in the String pool ("1111","2222","11112222")by 1st and 2nd and 3rd stmnts
case 5: 1.final String s1 = "1111";
final String s2 = "2222";
final String s3 = s1 +s2;
- 3 String objects / created in the String pool ("1111","2222","11112222")by 1st and 2nd and 3rd stmnt
case 6: 1. String s1 = "1111";
String s2 = "2222";
String s3 = s1 +s2;
- 2 String objects created in the String pool ("1111","2222")by 1st and 2nd / 1 in heap with content as "11112222" by 3rd stmnt since the individual comp s1 and s2 are not constant valued String objects. S1 and s2 may change it's content if they want in course of their life lifetime unlike final String s1="1111"; which can't change its value.
case 7: 1. String s1 = "1111";
String s2 = "2222";
String s3 = s1 +s2;
- 2 String objects created in the String pool ("1111","2222")by 1st and 2nd / 1 in heap with content as "11112222" by 3rd stmnt.
case 8: 1. String s1 = new String("1111");
- 1 String object created in the heap as a result of this new operation with content as "1111";
- As I asked you to blindly remember the fact that, whenever the Compiler sees a CONSTANT VALUED String object it creates in the String pool. So when the compiler compiles itself it creates a String pool object "1111". At run time the new operation creates ANOTHER HEAP String object whose content is again "1111".
[ YOUR DOUBT TO BE ANSWERED HERE IN THIS CASE 7 ]. As I said before, to assume these are the ONLY statements in a class definition and no other statements, we can be SURE OF there is NO PRE-EXISTING String pool object "1111" for case 7. So this brings down to the total objects created are 2.
If there would have been another code already which comes BEFORE these code in the source program in the order as they are written, then this time new String("1111") will create only 1 heap object right? No String pool object. So if that is a case like the following
String s0 = "1111";
String s1 = new String("1111");
then the 2nd stmnt alone will create ONLY 1 in the heap NOT in POOL since 1st stmnt has ALREADY created one in POOL.
Case 10 String s0 = new String("1111"); // 1 in heap , 1 in pool
String s1 = new String("1111"); // 1 in heap alone (NO POOL)
String s2 = new String("1111"); // 1 in heap alone (NO POOL)
String s3 = new String("1111"); // 1 in heap alone (NO POOL)
String s4 = new String("1111") + new String("2222");
// 1 in heap alone ("11111111") (1 POOL - "2222")
Actually what really happens internally in this case is
- 1 pool object created - "2222";
- 2 heap objects due to 2 new(..) - "1111" ,"2222"
- an intermediate Stringbuffer created in heap
- the 2 heap objs "1111", "2222" are appended to String buffer
- the .toString() of this StringBuffer is called internally, which returns another heap object with content "11112222"
So the in between created objects in heap "1111" and "2222" are eligible for GC
(1) an intermediate String buffer is created in the heap;
(2) 2 String objects created in heap
I tried to explain the concept. But the internals are not needed for the SCJP exam purpose.

regds
maha anna
[This message has been edited by maha anna (edited July 25, 2000).]