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

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

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

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

我将你的代码包装在一个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."":()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."":()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对象。

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

代码

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

创建3个对象。

我的原因:

Java中的基本数据类型不是对象,也不从Objectinheritance。 所以int i=0; and int j=1; 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连接的值。

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

只有1 ,String对象被连​​接起来。

只有1即用于打印字符串。

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

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

 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也可能会创建背后的对象,如果没有外部工具, 您无法了解它们 。 因此“至少”。

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

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

将有2个对象。

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

  1. int i
  2. int j
  3. “我的价值是”
  4. “我的价值是”+我
  5. “我的价值是”+ i +“j值是”
  6. “我的价值是”+ i +“j值是”+ j

在上面的示例中创建了总共六个对象。

5个对象

  1. “我的价值是”。将形成一个String对象。
  2. “我的价值是” + i 。这个连接操作将形成第二个对象。
  3. “j值是”将形成第三个对象。
  4. “我的值是”+ i + “j值是”。第四个因为连接而形成的对象。
  5. “我的值是”+ i +“j值是” + j。这最后的连接将形成第5个对象。