class StringTest1
{
public static final void main(String... a)
{
String str1="JAVA";
String str2="WORLD";
String str3=str1+str2;
}
}
在此过程中将创建多少个对象?我想会创建3个对象。
class StringTest2
{
public static final void main(String... a)
{
String strTest="JAVA"+"WORLD";
}
}
在这个过程中会创建多少个对象?有多少对象是可访问的?有人告诉我"JAVA"+"WORLD“是一个表达式,它不会存储在字符串池中。
发布于 2013-07-01 02:16:49
在第一个示例中,您将得到三个String
对象。您实际上可以在字节码中看到这一点。
假设您有以下代码:
public class StrTest {
public static void main(String[] args) {
String str1 = "JAVA";
String str2 = "WORLD";
String str3 = str1 + str2;
String strTest = "JAVA" + "WORLD";
}
}
得到的字节码是:
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
}
您可以看到,Java编译器已经在字符串池中为"JAVA"
和"WORLD"
创建了两个String
实例。为了将这两者附加在一起,它创建了一个StringBuilder
实例并附加了这些值。之后,它在该实例上调用toString()
,这将创建一个内部包含"JAVAWORLD"
的新String
实例。
在第二种情况下,您最终只有一个String
实例,因为Java编译器足够智能,能够看到您基本上拥有的是一个常量,因此它通过计算该表达式并在包含"JAVAWORLD"
的字符串池中创建 one String
实例来执行一些编译时优化。然后将对该实例的引用分配给strTest
。
关于字符串"JAVA"
、"WORLD"
和"JAVAWORLD"
,这些基本上都是被套住的字符串。因为字符串在Java中是不可变的,所以您只需要一个对唯一实例的引用,该实例可以在代码中的多个位置重用。这基本上是一种节省内存的方法。
所以总结一下:
String
实例:两个在池中,一个是在追加后新建的(还创建了一个StringBuilder
实例来追加两个字符串,导致总共4个对象)。发布于 2013-07-01 02:17:47
String str1="JAVA";
String str2="WORLD";
String strTest="JAVA"+"WORLD";
这三行中的每一行都将创建一个String对象。但是,如果代码被多次生成,那么它将始终是同一个对象。此外,每个String对象将包含一个char[]
对象,因此从技术上讲,它是每行2个对象。
String str3=str1+str2;
假设javac
不能对此进行优化,它将编译为
String str3 = new StringBuilder(str1).append(str2).toString();
因此,它不仅会创建一个字符串,还会创建一个在代码中无法访问的StringBuilder。因此,在最坏的情况下,会创建4个对象: String、StringBuilder和to char数组(因为它必须在append
期间调整大小)
发布于 2013-07-01 02:09:37
在第一种情况下,编译器不能确定str1
和str2
将具有什么值,因此它不是常量表达式,因此将在运行时计算它。将有三个对象(两个来自字符串文字,一个创建为字符串的串联)。
在第二种情况下,编译器能够计算结果,因此将只有一个对象,就像您编写"JAVAWORLD"
一样
https://stackoverflow.com/questions/17393271
复制相似问题