Dan*_*Dan 17 java design-patterns flyweight-pattern
如果你有两个String实例,并且它们是相同的,那么在Java中它们将共享相同的内存.这是如何在引擎盖下实施的?
编辑:我的应用程序使用大量的String对象,其中许多是相同的.使用Java String常量池的最佳方法是什么,以避免创建自定义flyweight实现?
mat*_*t b 12
如果你有两个String实例,并且它们是相同的,那么在Java中它们将共享相同的内存
这实际上不是100%真实.
这篇博客文章很好地解释了为什么会这样,以及String常量池是什么.
查看源代码java.lang.String(整个java api 的源代码是JDK的一部分).
总结一下:一个String包含了一个子序列char[].这种支持char[]永远不会被修改.这是通过既没有泄漏也没有char[]在String课堂外捕获它来实现的.但是,有几个Strings可以共享相同的内容char[](请参阅实现String.substring).
如其他答案所述,还有实习机制.
字符串文字是用Java实现的,所以实际上只有一个String对象有多个引用(当它们相等时,情况并非总是如此).有关更多详细信息,请参阅java.net文章有关intern()的所有信息.
在3.10.5 JLS的字符串文字中还有一个很好的例子/解释,它讨论了字符串何时被实现以及它们何时是不同的.
这不是必须的。例子:
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true
Run Code Online (Sandbox Code Playgroud)
但:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false
Run Code Online (Sandbox Code Playgroud)
现在不鼓励第二种形式。有些人(包括我)认为这String甚至不应该有一个公共构造函数。上面的更好版本是:
String s1 = new String("hello").intern();
String s2 = new String("hello").intern();
System.out.println(s1 == s2); // true
Run Code Online (Sandbox Code Playgroud)
显然,您不需要为常量执行此操作String。这是说明性的。
关于这个最重要的一点是,如果你传入一个String或一个函数得到一个你不能依赖String感规范。一个规范 Object满足这个等式:
a.equals(b) == b.equals(a) == (a == b)
Run Code Online (Sandbox Code Playgroud)
用于非null实例a,b,给定的Class。