有多少个对象创建(How many objects are created)

2019-06-24 04:26发布

我有一个关于用法的讨论String S和StringBuffer S IN的Java。 多少对象在每个这两个例子都是创造出来的?

例1:

String s = "a";
s = s + "b";
s = s + "c";        

例2:

StringBuilder sb = new StringBuilder("a");
sb.append("b");
sb.append("c");

在我看来,例1将创建5和Ex 2将创建4个对象。

Answer 1:

您可以通过分析Java字节码(利用确定答案javap -c )。 实施例1创建两个StringBuilder对象(见行#4)和两个String对象(见行#7),而实施例2创建一个StringBuilder对象(见行#2)。

请注意,您还必须采取char[]对象考虑(因为数组是在Java对象)。 StringStringBuilder对象使用底层两者实现char[] 因此,实施例1创建八个对象和实例2生成的两个对象。

实施例1:

public static void main(java.lang.String[]);
  Code:
   0:   ldc             #2; //String a
   2:   astore_1
   3:   new             #3; //class java/lang/StringBuilder
   6:   dup
   7:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   10:  aload_1
   11:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   14:  ldc             #6; //String b
   16:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   19:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   22:  astore_1
   23:  new             #3; //class java/lang/StringBuilder
   26:  dup
   27:  invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   30:  aload_1
   31:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   34:  ldc             #8; //String c
   36:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   39:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   42:  astore_1
   43:  return   
}

实施例2:

public static void main(java.lang.String[]);
  Code:
   0:   new             #2; //class java/lang/StringBuilder
   3:   dup
   4:   ldc             #3; //String a
   6:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
   9:   astore_1
   10:  aload_1
   11:  ldc             #5; //String b
   13:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   16:  pop
   17:  aload_1
   18:  ldc             #7; //String c
   20:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   23:  pop
   24:  return  
}


Answer 2:

我用了一个内存分析器得到确切的计数。

在我的机器,第一个例子创建了8个目标:

String s = "a";
s = s + "b";
s = s + "c";
  • 型的两个对象String ;
  • 类型的两个对象StringBuilder ;
  • 类型的四个对象char[]

在另一方面,第二实施例:

StringBuffer sb = new StringBuffer("a");
sb.append("b");
sb.append("c");

创建2个对象:

  • 类型的一个对象StringBuilder ;
  • 类型的一个对象char[]

这是使用JDK 1.6u30。

PS到了作出比较公平的,你可能应该调用sb.toString()在第二个例子中结束。



Answer 3:

在创建的对象的条件:

实施例1创建8个对象:

String s = "a"; // No object created
s = s + "b"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String)
s = s + "c"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String)

实施例2 2创建对象:

StringBuffer sb = new StringBuffer("a"); // 1 StringBuffer + 1 char[] (in SB)
sb.append("b"); // 0
sb.append("c"); // 0

为了公平起见,我不知道新的char []实际上在Java中创建一个对象(但我知道他们创建的)。 由于AIX指出了这一点。



Answer 4:

答案是联系在一起的语言(编译器和运行库)的具体实现。 甚至到了特定优化选项或不存在。 而且,当然,执行的版本(并明确了JLS它符合)。 所以,最好的最小值和最大值的词来说话。 事实上,这项工作提供了一个更好的

对于练习1,对象的最小数目是1(编译器实现仅存在所涉及的常数以及用于仅产生代码String s= "abc" ; 最大的可能只是任何事情,这取决于实现,但一个合理的估计是8(在另一个答案,因为某些配置所产生的数量也给出)。

对于练习2,对象的最小数量是2的编译器没有办法知道,如果我们已经取代StringBuilder的具有不同语义的定制版本的方式,所以不会进行优化。 最大可能约为6,在极存储器节约的StringBuilder实现膨胀的背衬char[]数组一次一个字符,但在大多数情况下,将2太。



文章来源: How many objects are created