System.out.println()是否创建了一个String如果我们连接?

时间:2014-05-19 15:29:02

标签: java string

我在接受采访时被问到这个问题。 有人能解释我正确的答案吗?

这是代码。

String s1= "hellow";
String s2= "Hellow again";

System.out.println(s1+s2);

上面的代码中创建了多少个字符串? 我认为这将是3.任何建议?

7 个答案:

答案 0 :(得分:4)

字符串文字"hellow""Hellow again"位于字符串池中。

现在,当我们与s1 + s2连接时,真正发生的是以下内容:

new StringBuilder(s1).append(s2).toString()

本身会创建一个新的Stringsee for yourself)。所以它取决于你的意思"创造&#34 ;;如果您要询问代码段末尾有多少String个对象,则答案为3.但请注意s1+s2生成的字符串不会保留,因此符合条件在打印后进行垃圾收集。

答案 1 :(得分:2)

这个答案基本上是arshajii答案的延伸

答案全部取决于你的面试官“创造”的含义,技术上也取决于其他代码的存在。

如果您反汇编仅由该代码段生成的字节码,则可以得到:

 public static void main(java.lang.String[]);
Code:
   0: ldc           #2                  // String hellow
   2: astore_1      
   3: ldc           #3                  // String Hellow again
   5: astore_2      
   6: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
   9: new           #5                  // class java/lang/StringBuilder
  12: dup           
  13: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
  16: aload_1       
  17: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  20: aload_2       
  21: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  24: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  27: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
  30: return        

因为"hellow""Hellow again"是源代码中的字符串文字,所以它们在编译时被置于常量池中,因此在程序启动时也会出现。如您所见,字符串"hellow""Hellow again"只是加载(ldc == load constant)。它们不是由以上代码段创建的。唯一创建的String是来自StringBuilder

final

现在,如果您声明字段public static void main(java.lang.String[]); Code: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String hellowHellow again 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return ,则可以获得:

String

基于此,您还可以认为 no final对象是由上面的代码片段创建的,因为编译器可以优化此语句。这可能不是采访者所寻求的答案,因为它取决于{{1}}在场。

答案 2 :(得分:0)

字符串是不可变的,因此s1 + s2创建一个新的String实例。如果你想避免这种情况,你应该使用StringBuffer。

答案 3 :(得分:0)

Java中的operator hierarchy表示,在方法调用之前正在评估字符串连接。因此,括号中的表达式首先创建一个新的String,然后写入标准输出。

我的回答:3

答案 4 :(得分:0)

答案取决于实现,它还取决于上下文......以及创作的含义。

这些代码行的执行为连接创建了一个String对象,可能还为println调用 1 中的其他对象创建了一个println(s)对象。每次应用程序执行这些行时都会发生这些创建。

加载代码时将至少再创建两个String对象,并为String文字创建String对象。但是,这是一次性的......


1 - 在某些类库中,print(s + newline)实现为println。因此,String调用可以创建另一个{{1}}对象。

答案 5 :(得分:0)

面试问题的正确答案可能不是“3”,而是上面讨论的一些(但不一定是全部)。他们肯定希望你知道+创造了一个字符串;可能需要一些意识,即常量s1s2作为编译时常量创建/存在;如果您知道添加final的效果,可能会给您留下深刻的印象。这些问题往往不是为了得到正确的答案,而是以正确的方式思考它们。

答案 6 :(得分:-1)

3就是答案。

但是使用StringBuilder(因为StringBuffer是StringBuilder的无用线程安全版本)。

您应该使用StringBuilder.append方法,而不是+运算符。