2011-05-06 187 views
4

这会创建多少个字符串?Java字符串优化

String test(String text) { 
    return "string 1 " + 
    text + " string 2 " + 
    "string 3"; 
} 
+0

动机是什么?这是面试问题还是什么? – leonbloy 2011-05-06 13:36:46

+3

哪个版本的Java?我相信多年来编译器已经进行了优化,这改变了字符串联合的性能,因此答案会有所不同。 – Codemwnci 2011-05-06 13:37:50

+1

一,只有一个 – MeBigFatGuy 2011-05-06 13:38:19

回答

6

没有新的串的呼叫都存在这里,存在的只有一个是在StringBuilder.toString,所以

java.lang.String test(java.lang.String); 
    Code: 
    Stack=3, Locals=2, Args_size=2 
    0: new #16; //class java/lang/StringBuilder 
    3: dup 
    4: ldC#18; //String string 1 
    6: invokespecial #20; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    9: aload_1 
    10: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    13: ldC#27; //String string 2 
    15: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    18: ldC#29; //String string 3 
    20: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    23: invokevirtual #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    26: areturn 
-1

这是

(new StringBuilder((new StringBuilder((new StringBuilder("String 1")).append(text).toString())).append("string 2 ").toString()).append("string 3").toString(); 

这3个stringbuilders和6串的等效。优化这个问题的方法是:

StringBuilder sb = new StringBuilder("string 1"); 
    sb.append(test); 
    sb.append(" string 2 "); 
    sb.append("string 3"); 
    return sb.toString(); 
+0

我只计算1个字符串,此方法'创建',其他字符串是在类加载时创建的,而不是由于此方法。 – MeBigFatGuy 2011-05-06 13:39:57

+2

这是完全不真实的。只有一个'StringBuilder'被构造,并且为每个后续字符串调用'append'。您显示的“优化”代码实际上就是编译器发出的代码。使用'javap -c'检查它。 – 2011-05-06 13:43:29

+0

@ gabuzo:*所有* JDKs *总是*做到这一点;他们一直都很聪明,可以在一行中使用“append”进行连接。它在循环中连接多个语句,这始终是bugbear。 – 2011-05-06 13:48:20

4

这是很容易通过编译代码,然后用javap -c检查字节码来回答。在这种特殊情况下,编译器应该产生这样

String result = new StringBuilder("string1"). 
    append(text).append("string2").append("string3").toString(); 

代码,所以这取决于你如何看待它,你可能会说只有一个,或者如果你是谁喜欢数文字作为其中的一个人“创造“,当他们使用,你可以说四。

+0

,如果你看看编译的代码,你会看到_NO_新的字符串调用。 (只有一个发生在StringBuilder.toString()) – MeBigFatGuy 2011-05-06 13:45:55

3

javap是你的朋友。我把你的代码S.java和使用javap -c S deassembled它:

Compiled from "S.java" 
public class S extends java.lang.Object{ 
public S(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public java.lang.String test(java.lang.String); 
    Code: 
    0: new  #2; //class java/lang/StringBuilder 
    3: dup 
    4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V 
    7: ldc  #4; //String string 1 
    9: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    12: aload_1 
    13: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    16: ldc  #6; //String string 2 
    18: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    21: ldc  #7; //String string 3 
    23: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    26: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    29: areturn 

} 

随着OpenJDK的1.6.0_22只有一个StringBuilder的,一个字符串创建。