Java的字符串实习生是轻量级吗?

Java的String内存池的实现是否遵循flyweight模式?

为什么我有这个疑问,我看到实习生没有涉及外在国家。 在GoF中我读到内在和外在状态之间应该有一个正确的平衡。 但在实习生中,一切都是内在的。

或者我们应该说没有关于属性的严格规则,只是共享对象以减少内存就足以称之为flyweight。

请帮我理解。

是的String.intern()实现遵循flyweight模式。

正如javadoc所说

返回字符串对象的规范表示。 最初为空的字符串池由String类私有维护。

调用实习方法时,如果池已经包含等于此字符串对象的字符串(由equals(Object)方法确定),则返回池中的字符串。 否则,将此String对象添加到池中,并返回对此String对象的引用。

因此,对于任何两个字符串s和t,当且仅当s.equals(t)为真时,s.intern()== t.intern()才为真。

所有文字字符串和字符串值常量表达式都是实体。 字符串文字在Java语言规范的§3.10.5中定义

内化字符串位于“Perm Gen”空间和.intern()返回的字符串对象上,您可以使用operator ==因为.intern()始终返回相同值的相同对象。

然后记住.intern()方法不会产生泄漏,因为今天的JVM能够对池进行垃圾处理。

尝试阅读这篇文章 。

无论实习如何,Java String通过在字符串和通过substring和类似方法调用从它派生的字符串之间共享char[]来利用flyweight模式。 但是有一个反面:如果你接受一个巨大的字符串的小子串,巨大的char[]将不符合垃圾收集的条件。

注意:从OpenJDK版本1.7.0_06开始,上述内容已经过时:代码已更改,因此实例之间不再共享char[]substring()创建一个新数组。

您已正确识别Interning和Flyweight都基于相同的想法:缓存和共享公共状态。 使用Flyweight,在没有内部状态存储的极端情况下,不需要存在对象。 只有指向外部状态的指针仍然存在,然后Flyweight已成为实习生。

Interning“真的”是否是一种Flyweight只是对定义的争论。 最重要的是理解如何将一个人视为另一个人的专业实例,这样你就会很好。

就像其他人所说的那样,String.intern()就是关于缓存的。 它返回池中已存储的字符串文字的引用。 通过这种方式,它与flyweight模式类似,因为它使用现有对象,从而降低了内存消耗并提高了性能(尽管实习生在字符串池中也有自己的查找性能开销)。 因此,这两者似乎相似,但实际上并非如此。

Flyweight是关于共享对象immutables内部。 实习只是缓存整个对象。