我对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
Run Code Online (Sandbox Code Playgroud)
请让我知道我的理解是否正确?
你的前两行几乎是正确的.从技术上讲,这两行代码不会自己创建任何对象 - 字符串文字实际上是在编译时处理的,并放在字节码文件的常量池中,这意味着String
在类第一次创建实际对象时在您编写的任何代码运行之前加载.因此,如果您要对代码的前两行进行反编译,那么您将得到以下结果:
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
Run Code Online (Sandbox Code Playgroud)
如您所见,任何String
一行都不会创建任何对象.字节码只是将String
常量池(ldc
均值load constant
)中的预先存在的值分配给那些变量
接下来的两行有点不同.如果将链式调用拆分为组件部分,可能更容易弄清楚发生了什么:
String s2 = new String("Android");
s2 = s2.intern();
String s3 = new String("java");
s3 = s3.intern();
Run Code Online (Sandbox Code Playgroud)
这会被编译为这个字节码:
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
Run Code Online (Sandbox Code Playgroud)
因此,您可以看到该new
关键字触发了新String
对象的构造.然后"Android"
从常量池加载字符串并用于创建字符串.然后将其存储到变量中.紧接着,该变量被解除引用,intern()
被调用,并且结果存储回变量中.这段代码与您的代码之间的唯一区别在于String
构造和实习之间的额外存储/负载.
因此,对于每个s2
和s3
,只String
创建一个对象 - 因此,您只看到两个方法<init>
总计.所有intern()
操作都是检查字符串池中是否已存在该字符串,如果存在,则返回该引用.
归档时间: |
|
查看次数: |
397 次 |
最近记录: |