百木园-与人分享,
就是让自己快乐。

通俗易懂的了解String中的intern方法

首先,先看一下intern方法(JDK1.8)的官方文档:

 

全是英文,阅读起来有点困难怎么办?没关系,博主对此做了翻译:

返回字符串对象的规范表示形式。

最初为空的字符串池由类字符串私人维护。

调用intern方法时,如果池中已包含一个字符串,该字符串等于由equalsobject)方法确定的该字符串对象,则返回池中的字符串。否则,将此字符串对象添加到池中,并返回对该字符串对象的引用。

因此,对于任意两个字符串sts.intern()==t.intern()当且仅当s.equalst)为真时才为真。

所有文字字符串和字符串值常量表达式都是内部的。字符串文字在Java的第3.10.5节中定义语言规范。

返回值:

与此字符串具有相同内容,但保证来自唯一字符串池的字符串。

还是看不懂怎么办?以下博主将对intern方法进行全面讲解:

要想具体了解String中的intern方法,首先你要了解一下JVM的内存结构,认识串池(StringTable)

以下是JDK1.6相关的内存结构:

 

 

以下是JDK1.8相关的内存结构:

 

 

随着内存结构的改变String中的intern方法功能也发生了改变。

本片文章主要以JDK1.8为例,先看以下这段代码:

 

public class Test{
    String s1 = new String(\"a\") + new String(\"b\");
    s1.intern();//
    String s2 = \"ab\";//
    System.out.println(s1 == s2);
    
}

 

运行结果为true;

具体原因是:当String对象调用intern方法时,如果池中未包含相同的字符串,将此字符串对象添加到池中,并返回对该字符串对象的引用。

运行的主要流程为:

(1)String s1 = new String(“a”) + new String(“b”);
首先创建StringBuilder对象,用于字符串拼接;
然后在堆中创建了String(“a”)对象,然后在字符串常量池中放入字符串\"a\",再做StringBuilder的append操作;
然后在堆中创建了String(“b”)对象,然后在字符串常量池中放入字符串\"b\",再做StringBuilder的append操作;
最后对StringBuilder做toString操作,注意此时只会在堆内存创建对象,并不会在串池中创建。

(2)s1.intern();
常量池中不直接放入\"ab\",而是引用堆中已经创建的String(“ab”)。

(3)String s2 = “ab”;
s2指向字符串常量池中的\"ab\",实际上是指向了堆中的String(“ab”)。

但当我们调换①和②的位置时结果为falus,这是什么原因呢?

调用intern方法时,如果池中已包含一个字符串,该字符串等于由equals(object)方法确定的该字符串对象,则返回池中的字符串。

所以,当调换①和②后,代码将会首先在串池中创建一个“ab”,然后当执行s1.intern()时就会直接返回串池中的\"ab\",但此时堆内存中的String(\"ab\")对象和串池中的\"ab\"不为同一个,于是返回falus。

 

但别忘了,JDK1.6和JDK1.8却是不同的。

JDK1.6的作用是:检查常量池里是否存在“ab”这么一个字符串,如果存在,就返回池里的字符串,如果不存在,该方法会把“ab”添加到字符串池中(此时这个\"ab\"并不是堆内存中的那个String(”ab“)而是一个新的\"ab\"),然后再返回它的引用。所以如果是JDK1.6下以上两张情况将都返回falus。

 


来源:https://www.cnblogs.com/wffwh/p/16694591.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 通俗易懂的了解String中的intern方法

相关推荐

  • 暂无文章