繁体   English   中英

String.intern()的返回解释

[英]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
  1. 由于"Cattie & Doggie"不存在"Cattie & Doggie" ,s1.intern()会将当前对象引用放入池中并返回自身,因此s1.intern() == s1 ;
  2. "Cattie & Doggie"现在已经在游泳池中,所以字符串文字"Cattie & Doggie"将只使用池中的引用,实际上是s1 ,所以我们再次true ;
  3. new StringBuilder().toString()将创建一个新实例,而"java"已经在池中,然后在调用s2.intern()时将返回池中的引用,所以s2.intern() != s2和我们有false
  4. new String()也将返回一个新实例,但是当我们尝试s3.intern() ,它将返回池中先前存储的引用,该引用实际上是s1所以s3.intern() != s3并且我们有false ;
  5. 正如#2已经讨论过的那样,字符串文字"Cattie & Doggie"将返回已经存储在池中的引用(实际上是s1 ),所以s3 != "Cattie & Doggie" ,我们又false了。

感谢@Sunny提供了获取所有interned字符串的技巧。

仅当String池在该调用之前不包含值为“java”的Strings2.intern()才会返回s2引用的实例。 JDK类在执行代码之前实际执行一些String “java”必须是其中之一。 因此, s2.intern()返回先前实例化的实例而不是s2

另一方面,JDK类没有实现任何其值等于“Cattie&Doggie”的String ,因此s1.intern()返回s1

我不知道任何预先实习的字符串列表。 这样的列表很可能被认为是一个实现细节,它可能因不同的JDK实现和JDK版本而有所不同,不应该依赖。

当在String对象上调用intern()方法时,它会查找池中此String对象包含的字符串,如果在那里找到该字符串,则返回池中的字符串。 否则,将此String对象添加到池中,并返回对此String对象的引用。

所以java字符串必须已经在池中。 因此它是虚假的。

您可以在池中打印所有字符串

如何打印整个String池?

以下是使用openjdk获取所有字符串的示例

字符串文字(像“字符串”这样硬编码的字符串文字)已由编译器为您实现。 但是那些以编程方式获取的字符串不会,并且只有在使用.intern()方法时才会被实现。

通常你不会手动实习字符串,除非你知道你将在内存中存储大量重复字符串,这样你就可以节省大量内存。

这里解释了: Java String interning是什么?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM