看完这篇,我不信你对String.intern()还有疑惑

本文探讨了Java中的String.intern()方法,详细解释了不同JDK版本下该方法的行为差异,包括JDK6、JDK7+和JDK12。文章介绍了常量池的历史变迁,从永久代到堆再到元空间,并通过代码示例展示了intern()如何影响字符串引用。文章还分析了intern()的源码,讨论了常量池的管理和性能考虑。
摘要由CSDN通过智能技术生成

常量池

Java虚拟机管理的内存包含以下几个运行时数据区域

thread-java-running-data-area.png

方法区与java堆一样,是各个线程共享的内存区域,用于存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

JDK8之前很多人叫它永久代(这里可以联想下年前代,老年代),是因为当时HotSpot虚拟机的设计团队选择将收集器的分代设计扩展至方法区,或者说使用永久代来实现方法区而已。

这样使得HotSpot的垃圾收集器能像管理Java堆一样管理这部分内存。但是对于其他虚拟机实现是不存在这个概念的。

运行时常量池(Runtime ConstantPool)是方法区的一部分。

Class文件中除了有类的版本、字、方法、接口等描述信息外,还有一项信息是常量池表(ConstantPoolTable),用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

String str = “think123” 其中的think123就直接保存在常量池中

运行时常量池存了在编译器能产生之外,在运行期间也可以将新的常量放入池中,这种特性被利用最多的就是String类的intern()方法。

String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用
否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。

伪代码类似如下:


if(StringPool.contains(search_string)) {
  
  return search_string_addr;
}

search_string_addr = StringPool.add(search_string);

return search_string_addr;

神奇的代码

下面的代码你猜猜会输出什么?

public class Main {
   

  public static void main(String[] args) {
   

    String s1 = new StringBuilder().append("think").append("123").toString();

    System.out.println(s1.intern() == s1);

    String s2 = new StringBuilder().append("ja").append("va"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Java 中,String.intern() 方法返回字符串对象在虚拟机的字符串池中的引用(如果池中已经包含了一个等于此 String 对象的字符串),否则,它将此 String 对象添加到池中,并且返回对此 String 对象的引用。字符串池是一个由 String 对象组成的集合,用于存储在程序中反复使用的字符串。使用字符串池可以减少字符串对象的数量,从而节省内存空间。 举个例子: ``` String s1 = "Hello"; String s2 = "Hello"; String s3 = new String("Hello"); System.out.println(s1 == s2); // true System.out.println(s1 == s3); // false s3 = s3.intern(); System.out.println(s1 == s3); // true ``` 在上面的代码中,由于 s1 和 s2 是相同的字面值,所以它们指向的是同一个字符串对象。但是 s3 是通过 new 运算符创建的新对象,所以 s1 和 s3 不是同一个对象。但是通过调用 s3.intern() 方法并将返回值赋给 s3,s3 就指向了字符串池中的 "Hello" 字符串,所以 s1 和 s3 指向的是同一个对象。 ### 回答2: Twitter是一家全球著名的社交媒体平台,通过推文(tweets)的方式使用户能够分享自己的想法、看法、图片和链接等内容。String.internJava中的一个方法,用于在运行时将字符串实例添加到内部字符串池中,并返回对该字符串实例的引用。 在Twitter的背后,有一个庞大的后台系统,用于处理大量的用户数据和内容。在这个系统中,处理字符串是非常常见的操作,因此String.intern方法在这里也发挥了重要的作用。 Twitter对String.intern的使用主要是为了优化内存和提高性能。由于用户在推文中频繁使用相同的字符、词语和短语,将这些重复的字符串实例添加到内部字符串池中可以减少内存消耗。而使用String.intern方法的返回值作为字符串的引用,可以提高字符串的比较效率,从而提高整个系统的性能。 除了内存和性能方面的优化,String.intern还能够在字符串比较时保证唯一性。当多个线程或不同的部分都使用了String.intern方法来获取字符串的引用时,它们得到的引用都是相同的。这样可以有效地避免同样的字符串被多次创建,并且可以确保在比较字符串时得到正确的结果。 综上所述,Twitter对String.intern的使用是为了优化内存、提高性能以及确保字符串的唯一性。通过将重复的字符串实例添加到内部字符串池中,并使用String.intern方法返回的引用来进行字符串的操作,Twitter能够更高效地处理用户的大量数据和内容,提供更好的用户体验。 ### 回答3: Twitter对于String.intern()的使用要根据不同的情况。String.intern()方法字符串常量池中查找是否存在相同值的字符串,如果存在则返回该字符串的引用,否则将该字符串添加到常量池中并返回引用。 在Twitter中,由于字符串的高频使用,使用String.intern()可以带来一些好处。首先,由于常量池中的字符串存在一份,使用intern()可以节省内存空间。对于一些频繁创建的字符串对象,如标识符、URL等,通过intern()方法可以使这些对象在内存中只存在一份,从而减少内存占用。 其次,使用String.intern()可以提高字符串的比较效率。由于常量池中的字符串只存在一份,使用intern()方法可以通过引用比较来判断字符串是否相等,而不需要逐个字符比较的过程。这对于Twitter这样的大规模社交平台来说,可以在处理大量文本数据时提高效率。 然而,需要注意的是,对于较短的字符串或者不频繁使用的字符串,使用intern()可能造成性能损失。String.intern()方法需要在常量池中进行查找和添加操作,这可能消耗一定的时间和资源。因此,在使用intern()方法时需要权衡利弊,并根据实际情况来决定是否使用。 综上所述,Twitter在高频使用字符串的情况下,可以考虑使用String.intern()方法来节省内存和提高效率。但需要注意的是,在使用时需要根据具体情况进行权衡,并在性能损失较大的情况下避免使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值