Java编译器是否有效地处理内联字符串?
问题描述:
static final String memFriendly = "Efficiently stored String";
System.out.println(memFriendly);
2.
System.out.println("Efficiently stored String");
威尔Java编译器处理两个(1 2和)的这些相同的方式?通过高效率,我指的是运行时内存利用率以及代码执行时间。例如第一种情况可以在堆栈加载变量memFriendly上花费更多时间吗?
答
public static void main(String[] args) {
System.out.println("Hello world!");
String hola = "Hola, mundo!";
System.out.println(hola);
}
这里是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
外貌像第二个字符串被存储,w这里第一个直接传递给方法。
这是用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
答
在这种情况下,编译器将处理两者相同。
任何时候在编译时定义一个字符串,Java都会优化字符串的存储。
如果在运行时定义字符串,则Java无法执行相同的optomization。
答
您拥有的代码是平等的,因为字符串文字会被编译器自动执行。
如果你真的关心字符串性能,并且会一遍又一遍地重复使用相同的字符串,那么应该查看字符串类的实习方法。
http://java.sun.com/javase/6/docs/api/java/lang/String.html#intern()
答
这被覆盖在Java Language Spec:
每个字符串文字是参考 (§4.3)到一个实例(第4.3.1节,§12.5)类字符串 ( §4.3.3)。字符串 对象具有固定值。字符串 文字 - 或者更一般地说,字符串 即表达式(§15.28)的值 - 被“interned”如此 以共享唯一实例,使用 方法String.intern。
您还可以使用javap工具查看自己。
对于此代码:
System.out.println("Efficiently stored String");
final String memFriendly = "Efficiently stored String";
System.out.println(memFriendly);
的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
我也相信,但我找不到具体的参考,我的意思是理论上的。谢谢 这是一篇很好的文章,但没有找到我想要的: http://muzso.hu/2009/03/05/strange-behaviour-in-java-compilers-string-concatenation-caused-by-编译时常量 – 2009-07-23 13:17:26
我找不到任何特定的文章或规格,很抱歉。 – jjnguy 2009-07-23 13:21:35