如果我们看一看String#substring方法实现:
new String(offset + beginIndex, endIndex - beginIndex, value);我们看到使用相同的原始内容(参数char []值)创建了一个新字符串。
因此,解决方法是使用new String(toto.substring(...))删除对原始char[]值的引用,并使其有资格使用GC (如果没有更多的引用)。
我想知道是否有什么特别的理由来解释这种实施。为什么该方法不为自己创建新的更短的字符串,以及为什么她保留完整的原始值?
另一个相关的问题是:在处理子字符串时,我们应该始终使用new String(...)吗?
发布于 2012-06-20 09:20:09
我想知道是否有什么特殊的原因解释了这个实现。为什么该方法不为自己创建新的更短的字符串,以及为什么她保留完整的原始值?
因为在中,大多数用例都是以这种方式工作的substring()更快。至少,这就是Sun /Oracle的经验测量结果所显示的。通过这样做,实现避免了分配支持数组和将字符复制到数组。
这只是一个非优化,如果你必须然后复制字符串,以避免内存泄漏问题。在绝大多数情况下,子串在相对较短的时间内就会变成垃圾,并且不会有长期的内存泄漏。
假设,Java可以提供两个版本的substring,一个是当前的行为,另一个是用自己的支持数组创建字符串。但这将鼓励开发人员浪费大脑周期来思考使用哪个版本。还有一个基于子字符串的实用方法的问题.例如,类似于Pattern / Matcher类。所以我认为他们没有这么做是件好事。
发布于 2012-06-20 09:14:06
因为String是immutable类
也见
发布于 2012-06-20 09:22:17
这种实现的原因是效率。通过指向与原始字符串相同的char[],不需要复制数据。
不过,正如你已经暗示过的那样,这也有其不利之处。如果原始字符串是长的,您只想获得其中的一小部分,并且在此之后不再需要原始字符串,那么完整的原始数组仍然会被引用,不能被垃圾收集。你已经知道如何避免那样做new String(original.substring(...))了。
在处理子字符串时,
应该总是使用
new String(...)吗?
不,不总是这样。只有当你知道它可能会引起问题的时候。在许多情况下,引用原始char[]而不是复制数据更有效。
https://stackoverflow.com/questions/11116292
复制相似问题