class StringTest1
{
public static final void main(String... a)
{
String str1="JAVA";
String str2="WORLD";
String str3=str1+str2;
}
}
Run Code Online (Sandbox Code Playgroud)
在此过程中将创建多少个对象?我想会创建3个对象.
class StringTest2
{
public static final void main(String... a)
{
String strTest="JAVA"+"WORLD";
}
}
Run Code Online (Sandbox Code Playgroud)
在此过程中将创建多少个对象?可以访问多少个对象?有人告诉我"JAVA"+"WORLD"是一个表达式,它不会存储在字符串池中.
在第一个示例中,您将最终得到三个String对象.您实际上可以在字节码中看到这一点.
假设您有以下代码:
public class StrTest {
public static void main(String[] args) {
String str1 = "JAVA";
String str2 = "WORLD";
String str3 = str1 + str2;
String strTest = "JAVA" + "WORLD";
}
}
Run Code Online (Sandbox Code Playgroud)
生成的字节码是:
public class StrTest {
public StrTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String JAVA
2: astore_1
3: ldc #3 // String WORLD
5: astore_2
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: ldc #8 // String JAVAWORLD
27: astore 4
29: return
}
Run Code Online (Sandbox Code Playgroud)
你可以看到,Java编译器设立了两个String实例为"JAVA"和"WORLD"在字符串池中.为了将这两者附加在一起,它创建了一个StringBuilder实例并附加了值.之后,它调用toString()该实例,在其中创建一个新String实例"JAVAWORLD".
在第二种情况下,您最终只得到一个String实例,因为Java编译器足够聪明,可以看到您基本上拥有的是一个常量,因此它通过计算表达式并在字符串中创建一个 String实例来执行一些编译时优化包含的池"JAVAWORLD".然后分配对该实例的引用strTest.
关于字符串"JAVA","WORLD"和"JAVAWORLD",这些基本上是实习字符串.由于字符串在Java中是不可变的,因此您只需要对一个唯一实例的一个引用,该实例可以在代码中的多个位置重用.这基本上是一种节省内存的方法.
总结一下:
String实例:池中有两个实例,一个在追加后新构造的StringBuilder实例(还创建了一个实例来附加两个字符串,总共产生4个对象).| 归档时间: |
|
| 查看次数: |
162 次 |
| 最近记录: |