[英]The return of String.intern() explained
考虑:
String s1 = new StringBuilder("Cattie").append(" & Doggie").toString();
System.out.println(s1.intern() == s1); // true why?
System.out.println(s1 == "Cattie & Doggie"); // true another why?
String s2 = new StringBuilder("ja").append("va").toString();
System.out.println(s2.intern() == s2); // false
String s3 = new String("Cattie & Doggie");
System.out.println(s3.intern() == s3); // false
System.out.println(s3 == "Cattie & Doggie"); // false
我很困惑为什么它们由于String.intern()
的返回值而产生不同的结果 ,它说:
调用实习方法时,如果池已经包含等于此字符串对象的字符串(由equals(Object)方法确定),则返回池中的字符串。 否则,将此String对象添加到池中,并返回对此String对象的引用。
特别是经过这两项测试:
assertFalse("new String() should create a new instance", new String("jav") == "jav");
assertFalse("new StringBuilder() should create a new instance",
new StringBuilder("jav").toString() == "jav");
我曾经读过一篇文章,谈论在其他事情之前被拘留的一些special strings
,但现在它真的很模糊。
如果pre-interned
存在一些字符串,是否有办法获得它们的列表? 我只是好奇他们会是什么。
感谢@Eran和@Slaw的帮助,我终于可以解释输出中刚刚发生了什么
true
true
false
false
false
"Cattie & Doggie"
不存在"Cattie & Doggie"
,s1.intern()会将当前对象引用放入池中并返回自身,因此s1.intern() == s1
; "Cattie & Doggie"
现在已经在游泳池中,所以字符串文字"Cattie & Doggie"
将只使用池中的引用,实际上是s1
,所以我们再次true
; new StringBuilder().toString()
将创建一个新实例,而"java"
已经在池中,然后在调用s2.intern()
时将返回池中的引用,所以s2.intern() != s2
和我们有false
new String()
也将返回一个新实例,但是当我们尝试s3.intern()
,它将返回池中先前存储的引用,该引用实际上是s1
所以s3.intern() != s3
并且我们有false
; "Cattie & Doggie"
将返回已经存储在池中的引用(实际上是s1
),所以s3 != "Cattie & Doggie"
,我们又false
了。 感谢@Sunny提供了获取所有interned
字符串的技巧。
仅当String池在该调用之前不包含值为“java”的String
, s2.intern()
才会返回s2
引用的实例。 JDK类在执行代码之前实际执行一些String
。 “java”必须是其中之一。 因此, s2.intern()
返回先前实例化的实例而不是s2
。
另一方面,JDK类没有实现任何其值等于“Cattie&Doggie”的String
,因此s1.intern()
返回s1
。
我不知道任何预先实习的字符串列表。 这样的列表很可能被认为是一个实现细节,它可能因不同的JDK实现和JDK版本而有所不同,不应该依赖。
当在String对象上调用intern()方法时,它会查找池中此String对象包含的字符串,如果在那里找到该字符串,则返回池中的字符串。 否则,将此String对象添加到池中,并返回对此String对象的引用。
所以java
字符串必须已经在池中。 因此它是虚假的。
您可以在池中打印所有字符串
以下是使用openjdk获取所有字符串的示例 。
字符串文字(像“字符串”这样硬编码的字符串文字)已由编译器为您实现。 但是那些以编程方式获取的字符串不会,并且只有在使用.intern()
方法时才会被实现。
通常你不会手动实习字符串,除非你知道你将在内存中存储大量重复字符串,这样你就可以节省大量内存。
这里解释了: Java String interning是什么?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.