3

I don`t have good understanding of intern method of String.

String  s1="java";  // should create  one  object in  String Constant  pool

String ss="java"; //  no object is created (java is already in String pool)..it  refers to object in String constant pool


String  s2= new String("Android").intern();  // should create  2 objects one in heap and     second  in String  constant  pool 

String s3=  new String("java").intern()//  i guess only  one  object is created on  heap and  s3 will  point to  object  in String constant  pool (as 'java' already exist).so  the object  in   heap is lost because  there is  no reference

please let me know my understanding is correct or not ?

Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
sar
  • 1,277
  • 3
  • 21
  • 48

2 Answers2

6

Your first two lines are almost correct. Technically, those two lines of code don't create any objects on their own -- the string literals are actually processed at compile time and placed into the constants pool in the bytecode file, which means the actual String objects are created when the class is first loaded, before any of the code you wrote runs. Thus, if you were to decompile the first two lines of your code you'd get this:

0: aload_0       
1: invokespecial #1                  // Method java/lang/Object."<init>":()V
4: aload_0       
5: ldc           #2                  // String java
7: putfield      #3                  // Field s1:Ljava/lang/String;
10: aload_0       
11: ldc           #2                  // String java
13: putfield      #4                  // Field ss:Ljava/lang/String;
16: return 

As you can see, no String objects are created by either line. The bytecode merely assigns preexisting String values from the constant pool (ldc means load constant) to those variables

The next two lines are a bit different. It's probably easier to figure out what's going on if you split the chained calls into their component parts:

String s2 = new String("Android");
s2 = s2.intern();
String s3 = new String("java");
s3 = s3.intern();

This gets compiled to this bytecode:

   0: new           #2                  // class java/lang/String
   3: dup           
   4: ldc           #3                  // String Android
   6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
   9: astore_1      
  10: aload_1       
  11: invokevirtual #5                  // Method java/lang/String.intern:()Ljava/lang/String;
  14: astore_1      
  15: new           #2                  // class java/lang/String
  18: dup           
  19: ldc           #6                  // String java
  21: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
  24: astore_2      
  25: aload_2       
  26: invokevirtual #5                  // Method java/lang/String.intern:()Ljava/lang/String;
  29: astore_2      
  30: return        

So you can see that the new keyword triggers the construction of a new String object. Then the string "Android" is loaded from the constant pool and used to create the string. This is then stored into a variable. Immediately after, the variable is dereferenced, intern() invoked, and the result stored back into the variable. The only difference between this code and your code would be the extra store/load in between String construction and interning.

So for each of s2 and s3, only one String object is created -- hence, you only see two methods with <init> total. All intern() does is check to see whether that that string already exists in the string pool, and if it does, returns that one reference.

awksp
  • 11,764
  • 4
  • 37
  • 44
  • Technically, the objects are created at link/classloading time, not compile time. – chrylis -cautiouslyoptimistic- May 22 '14 at 08:09
  • @chrylis Sure, I suppose you can put it that way... I was more thinking that all the information to create the objects was placed into the constant pool in the bytecode at compile time, but it'd make more sense to say the actual objects are created sometime during runtime... I'll correct my answer. – awksp May 22 '14 at 08:11
0

This line

String  s1="java";

or other lines containing string literals do not create String objects. They are created by JVM during loading of the classes containing string literals and placed in String pool.

As for String.intern() it does not create a new String, it just checks if a string is already in pool and if it's not there adds it to pool

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275