Mon*_*bal 4 java compiler-construction string optimization
1.
static final String memFriendly = "Efficiently stored String";
System.out.println(memFriendly);
Run Code Online (Sandbox Code Playgroud)
2.
System.out.println("Efficiently stored String");
Run Code Online (Sandbox Code Playgroud)
Java编译器会以同样的方式处理这些(1和2)吗?
仅供参考:有效地说,我指的是运行时内存利用率以及代码执行时间.例如,第一种情况可以在堆栈加载变量memFriendly上花费更多时间吗?
McD*_*ell 14
这包含在Java语言规范中:
每个字符串文字都是类String(第4.3.3节)的实例(第4.3.1节,第12.5节)的引用(第4.3节).String对象具有常量值.字符串文字 - 或者更一般地说,作为常量表达式(第15.28节)的值的字符串 - 是"实例化"以便使用String.intern方法共享唯一实例.
您也可以使用javap工具自己查看.
对于此代码:
System.out.println("Efficiently stored String");
final String memFriendly = "Efficiently stored String";
System.out.println(memFriendly);
Run Code Online (Sandbox Code Playgroud)
javap给出以下内容:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String Efficiently stored String
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc #3; //String Efficiently stored String
13: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
Run Code Online (Sandbox Code Playgroud)
public static void main(String[] args) {
System.out.println("Hello world!");
String hola = "Hola, mundo!";
System.out.println(hola);
}
Run Code Online (Sandbox Code Playgroud)
以下是javap显示为此代码的反汇编:
0: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #22; //String Hello world!
5: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: ldc #30; //String Hola, mundo!
10: astore_1
11: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
14: aload_1
15: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
18: return
Run Code Online (Sandbox Code Playgroud)
看起来第二个字符串正在存储,而第一个字符串直接传递给方法.
这是使用Eclipse的编译器构建的,这可以解释我的答案和McDowell的差异.
更新:如果hola声明为final结果aload_1,则结果如下(结果为否,如果我正确读取,则表示此字符串存储和内联,如您所料):
0: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #22; //String Hello world!
5: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: ldc #30; //String Hola, mundo!
10: astore_1
11: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
14: ldc #30; //String Hola, mundo!
16: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
19: return
Run Code Online (Sandbox Code Playgroud)