字符串连接期间创建的对象数

时间:2014-02-12 09:44:17

标签: java string object

有人可以告诉我在执行以下代码中的System.out.println语句时将创建多少个对象

int i=0;
int j=1;
System.out.print("i value is "+ i + "j value is "+j);

10 个答案:

答案 0 :(得分:7)

如果你真的想知道发生了什么,为什么不看字节码呢?

我将代码包装在main函数中,编译它然后用javap -c Test.class反汇编它。这是输出(使用Oracle Java 7编译器):

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

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_1
       3: istore_2
       4: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       7: new           #3                  // class java/lang/StringBuilder
      10: dup
      11: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      14: ldc           #5                  // String i value is
      16: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: iload_1
      20: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      23: ldc           #8                  // String j value is
      25: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      28: iload_2
      29: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      32: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      35: invokevirtual #10                 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
      38: return
}

在此方法中分配的唯一对象是StringBuilder(通过位置7处的new指令)。但是,invoke d的其他方法本身可能会分配一些东西,我非常怀疑StringBuilder.toString将分配一个String对象。

答案 1 :(得分:5)

这将创建一个StringBuilder对象(以及此对象在内部使用的任何对象),添加值,最后StringBuilder将创建一个带有结果的String对象。

答案 2 :(得分:2)

代码

int i=0;
int j=1;
System.out.print("i value is "+ i + "j value is "+j);

创建3个对象。

我的理由:

Java中的基本数据类型不是对象,不会从Object继承。所以  int i=0; and int j=1;不会成为对象。

现在System.out.print("i value is "+ i + "j value is "+j);包含String,它们是不可变的,对字符串的操作很昂贵。我们可以将操作拆分为此。

("i value is ").concat(i)  // creates one object let say obj1
obj1.concat("j value is ")   //creates another let say obj2
obj2.concat(j)            // creates the final string let say obj3;

在一个示例中,字符串操作str1.concat(str2)通过使用两个String对象完成,它创建第三个并更改引用,使其产生错觉,即它实际上是第一个字符串对象,即str1。因此str1将有一个新的String,它包含旧str1和str2连接的值。

这是我相信我有限的知识。如果我错了,请纠正我。

答案 3 :(得分:1)

只有1,String对象才会被连接。

答案 4 :(得分:1)

如果它确实依赖于实现,那么如果它被评估为:

StringBuilder sb = new StringBuilder("i value is ");
sb.append(i);
sb.append(j);
String newStr = sb.toString();

将有2个物体。

答案 5 :(得分:1)

仅用于打印字符串。

Thumb规则 - 每当完成字符串的连接时,就会创建一个新对象。

答案 6 :(得分:1)

编译器将代码转换为如下代码:

int i=0;
int j=1;
StringBuilder temp = new StringBuilder(); // creates a StringBuilder
temp.append("i value is "); // creates or re-uses a String
temp.append(i); // might create a String
temp.append("j value is"); // creates or re-uses a String
temp.append(j); // might create a String
String temp2 = temp.toString(); // creates a String
System.out.print(temp2);

这取决于你是否计算“i value is”和“j value is”字符串,它们被创建一次然后重新使用。

如果你计算它们,那么至少4,否则至少2。

实际上,每个String都有自己的char [],它实际上存储了字符串。所以这是7或3,而不是4或2。

StringBuilder也有一个char [],当你向它添加更多数据时,可能需要创建新的char []。 String.valueOf或System.out.print也可能在你的背后创建对象,如果没有外部工具,你就无法了解它们。因此“至少”。

答案 7 :(得分:0)

字符串是不可变的意味着您无法更改对象本身。
每次创建新的字符串对象时执行连接 所以在上面的例子中

  1. int i
  2. int j
  3. “我的价值是”
  4. “我的价值是”+ i
  5. “我的价值是”+ i +“j值是”
  6. “我的值是”+ i +“j值是”+ j
  7. 在上面的示例中创建了总共六个对象。

答案 8 :(得分:0)

5个对象

  1. &#34;我的值是&#34;。将形成一个String对象。
  2. &#34;我的值为&#34; + i 。此连接操作将形成第二个对象。
  3. &#34; j值是&#34;将形成第三个对象。
  4. &#34;我的值是&#34; + i + &#34; j值是&#34;。第四个因为连接而形成的对象。
  5. &#34;我的值是&#34; + i +&#34; j值是&#34; + j。此最后一个连接将形成第五个对象。

答案 9 :(得分:0)

您应该在这里考虑2点:

  1. 当您说String是不可变的时,如果您尝试更改值,它将创建一个新对象。
  2. 当您使用Literal(String s =“ Pool”)方式或使用new关键字(String s = new String(“ Heap and Pool”)编写代码时,会创建
  3. String对象,这里的new关键字是指堆,Literal“ “堆和池”是指字符串常量池)。

在这种情况下,以上答案是正确的。将创建五个String对象。