Java如何实现引擎盖下的绳子的轻量级图案?
-
04-10-2019 - |
题
如果您有两个字符串的实例,并且它们是平等的,则在Java中,它们将共享相同的内存。这是如何在引擎盖下实施的?
编辑:我的应用程序使用大量的字符串对象,其中许多对象是相同的。使用Java String Constant池的最佳方法是什么,以免创建自定义的轻量级实现?
解决方案
查看的源代码 java.lang.String
(整个Java API的来源是JDK的一部分)。
总结:一个字符串包裹一个子序列 char[]
. 。那个支持 char[]
永远不会修改。这是通过既没有泄漏也不捕获的来实现的 char[]
外面 String
班级。但是,有几个 Strings
可以共享相同的 char[]
(请参阅实施 String.substring
).
如其他答案中所述,还有一种实习的机制。
其他提示
字符串文字在Java中实施,因此实际上只有一个带有多个引用的字符串对象(当它们相等时,并非总是如此)。请参阅Java.net文章 关于实习生() 更多细节。
部分中还有一个很好的例子/解释 3.10.5字符串文字 在谈论何时实习以及何时与众不同的JL中。
这不是真的。例子:
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true
但:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false
现在,第二种形式不建议。有些人(包括我)认为 String
甚至不应该有公共构造师。以上更好的版本是:
String s1 = new String("hello").intern();
String s2 = new String("hello").intern();
System.out.println(s1 == s2); // true
显然,您不需要做到这一点 String
. 。这是说明性的。
重要的一点是,如果您通过了 String
或从您不能依靠的功能中获得一个 String
存在 典范. 。一种 典范 Object
满足这种平等:
a.equals(b) == b.equals(a) == (a == b)
对于非 -null
实例 a
, b,
给定的 Class
.
要小心的两件事:
- 不使用
new String("abc")
构造函数,只需使用文字"abc"
. - 学习使用 实习生() 字符串类中的方法。特别是当将字符串连接在一起或将char数组/字节数组/等转换为字符串时。
intern()
返回总是汇总的字符串。
如果您的相同的字符串来自一组固定的可能值,那么您想要的是类型安全的枚举。它不仅会减少您的字符串计数,而且还可以实现更扎实的应用程序。您的整个应用程序将知道此字符串附有语义,甚至可能采用一些便利方法。
我最喜欢的优化始终是可以作为制作代码的优化 更好的, ,不只是更快。在10中,有9次用混凝土类型替换字符串会导致更正确和自我纪录的代码。