2012-06-20 23 views
3

如果我们看一看在String#substring方法实现:关于字符串#子()方法

new String(offset + beginIndex, endIndex - beginIndex, value); 

我们看到一个新的String与相同原创内容创建(参数的char []值)。

因此,解决方法是使用new String(toto.substring(...))将引用删除到原始char []值并使其符合GC(如果不存在更多引用)。

我想知道是否有一个特殊的理由来解释这个实现。为什么这种方法不会创建新的更短的字符串,而是为什么她保留完整的原始值呢?

其他相关的问题是:我们在处理子串时是否总是使用new String(...)

回答

2

我想知道如果有一个特殊的原因,解释这个实现。为什么这种方法不会创建新的更短的字符串,而是为什么她保留完整的原始值呢?

由于使用情况是更快substring()这样的工作方式。至少,这就是Sun/Oracle的实证测量结果。通过这样做,实现避免了分配一个支持数组并将字符复制到数组中。

这只是一个非优化,如果您必须复制字符串以避免内存泄漏问题。在绝大多数情况下,子串在相对较短的时间内变成垃圾,并且没有长期的记忆泄漏。


可以想像,Java的设计者可能提供的substring两个版本,其中之一表现为当前,而创造了它自己的靠山阵列的String其他。但是这会鼓励开发人员浪费大脑思考使用哪个版本。然后存在建立在子字符串上的实用方法的问题......例如类似于Pattern/Matcher类。所以我认为他们没有这样做是件好事。

+0

好的,谢谢你的回答!所以你的意思是总是使用'new String()'改进内存管理,但是它不会让应用程序更快? –

+1

@ alain.janinm - 比这更复杂。一方面,'new String()'通常不能改善内存管理。另一方面,当它确实改善内存管理时,它会使应用程序更快。基本上,你必须了解你的应用程序的行为,以便知道这是否会改善事情。 –

+0

好吧,我想知道的一样,但我不确定!感谢启发! –

2

因为Stringimmutable

请参见

+1

** why **'String'的一个有用的补充链接是不可变的:[为什么String在Java中是不可变的?](http://javarevisited.blogspot.it/2010/10/why-string-is-immutable -in-java.html) –

+0

@LucaGeretti你应该建议作为对答案的编辑。 –

+0

@Kazekage:我不只是因为它是一个外部链接。我宁愿将(某些)内容整合到答案中。 –

1

该实施的原因是效率。通过指向与原始字符串相同的char[],不需要复制任何数据。

尽管如此,你也已经暗示了你自己。如果原始字符串很长,并且只想获取其中的一小部分,并且之后不再需要原始字符串,那么完整的原始数组仍然被引用并且不能被垃圾收集。你已经知道如何避免 - new String(original.substring(...))

处理子串时我们应该总是用new String(...)吗?

不,不是总是。只有当你知道它可能会导致问题。在许多情况下,参考原始char[]而不是复制数据更有效。

+0

感谢您的回答,它满足了Stephen C的回答! –