2012-03-09 49 views
1

例如,要扭转一个字符串,将有两种方式:的Java:两种方式之间Differrent当使用新的对象

第一:

String a = "StackOverFlow"; 
a = new StringBuffer(a).reverse().toString(); 

和第二个是:

String a = "StackOverFlow"; 
StringBuffer b = new StringBuffer(a); 
a = b.reverse().toString(); 

在上面的代码中,我有两个问题:

1)在第一个代码中,java是否创建了一个“虚拟对象”StringBuffer在内存之前做reverse并更改为String。 2)在上面的代码中,首先会比第二个更优化,因为它使GC更有效地工作? (这是我要问的一个主要问题)

谢谢:)

+0

通常代码清晰度比性能更重要,除非你知道你有问题。 – 2012-03-09 15:34:46

回答

1
  1. 第一种方式将创建一个非常真实的,根本不是“虚拟对象”StringBuffer
  2. 除非有b代码的最后一行低于其他文献,优化有足够的信息让环境,只要它与toString

完成的事实,有没有垃圾回收bb的变量不会使由new创建的对象更不真实。编译器可能会将这两个片段优化为相同的字节码。

1

StringBuffer b不为虚拟对象,是一个参考;基本上只是一个指针,驻留在堆栈中,并且非常小的记忆方式。因此,不仅它在性能上没有任何区别(GC与此示例无关),但Java编译器可能会完全删除它(除非它在代码中的其他位置使用)。

5

这两个片段都会创建相同数量的对象。唯一的区别是局部变量的数量。这可能甚至不会改变堆栈中有多少值 - 只是在第二个版本的情况下,其中一个堆栈槽有一个名称(b)。

区分对象变量是非常重要的。首先编写最易读的代码也很重要,而不是尝试微观优化。一旦你清楚,你应该测量工作代码,看看它是否足够快,以满足你的要求。如果不是,则应该对其进行配置以找出可以最有效地进行更改的位置,然后优化该部分,然后重新测量等。

0

回答第一个问题,是的,Java将创建一个StringBuffer对象。它的工作方式与您的想法完全相同。

对于第二个问题,我非常肯定Java编译器会为你处理这个问题。编译器不是没有缺陷,但我认为在这样一个简单的例子中,它会优化字节码。

只是一个提示,在Java字符串是不可变的。这意味着他们不能改变。所以,当你给一个字符串赋一个新的值时,Java会划出一块内存,把新的字符串值放入其中,并将该变量重定向到新的内存空间。之后,垃圾收集器应该过来并清除旧的字符串。

相关问题