【发布时间】:2013-05-02 15:44:16
【问题描述】:
有人告诉我,像这样创建 String 实例
String s = new String("Don't do this"); // explicit
有一个性能问题,因为它为双引号短语“不要这样做”创建了两个字符串实例,一个为 new String() 构造函数创建了一个实例!
今天我有时间自己测试一下,我创建了两个类:
public class String1 {
public static void main(String[] args) {
String s = new String("Hello");
System.out.println(s);
}
}
public class String2 {
public static void main(String[] args) {
String s = "Hello";
System.out.println(s);
}
}
这是javap的输出:
C:\jav>javap String1
Compiled from "String1.java"
public class String1 extends java.lang.Object{
public String1();
public static void main(java.lang.String[]);
}
C:\jav>javap String2
Compiled from "String2.java"
public class String2 extends java.lang.Object{
public String2();
public static void main(java.lang.String[]);
}
似乎它们是相同的,但是带有 -c 标志的输出是不同的。
C:\jav>javap -c String1
Compiled from "String1.java"
public class String1 extends java.lang.Object{
public String1();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String Hello
6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_1
14: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
17: return
}
C:\jav>javap -c String2
Compiled from "String2.java"
public class String2 extends java.lang.Object{
public String2();
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 Hello
2: astore_1
3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_1
7: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
}
所以这是我的问题:) 首先什么是“ldc”、astore_1 等?有没有描述这些的文件? 二是javac真的分不清这两句话是否相等??
【问题讨论】:
-
您可以通过查看Java Virtual Machine specification 了解这些含义。
-
重新
new String()操作,它完全按照您的指示进行操作。不过,该操作是所有 Java 构造函数中最快的,因为它“共享”原始字符串的字符数组。 (并不是说这样做有任何意义,除非在一些特殊情况下。) -
显式构造
String会创建另一个对象,该对象仅共享初始化值的实际字符串内容(char 数组)。所以你有一个额外对象的开销,
标签: java performance javac bytecode javap