加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – String常量池和实习生

发布时间:2020-12-15 01:02:29 所属栏目:Java 来源:网络整理
导读:我最近几天试图理解String常量池和inter的概念,在阅读了很多文章之后我理解了它的一些部分,但仍然对以下几点感到困惑: – 1.String a =“abc”这将在String Constant Pool中创建一个对象 但是以下代码行是否在字符串常量池中创建对象“xyz”? 字符串b =(“
我最近几天试图理解String常量池和inter的概念,在阅读了很多文章之后我理解了它的一些部分,但仍然对以下几点感到困惑: –

1.String a =“abc”这将在String Constant Pool中创建一个对象
但是以下代码行是否在字符串常量池中创建对象“xyz”?
字符串b =(“xyz”).toLowerCase()

2.

String c = "qwe"   
String d = c.substring(1)    
d.intern()   
String e = "we"

如果在类加载期间将文字“we”添加到String consant池中,如果是这样,为什么d == e结果为true,即使d未指向String Constant池也是如此

解决方法

字符串池正在延迟加载.如果你在字符串文字之前自己调用intern(),那么这是将进入字符串池的字符串的版本.如果你不自己调用intern(),那么字符串文字将为我们填充字符串池.

令人惊讶的是,我们可以在常量池之前影响字符串池;正如下面的代码片段所示.

要理解为什么两个代码片段具有不同的行为,重要的是要清楚

> the constant pool is not the same as the string pool.也就是说,常量池是存储在磁盘上的类文件的一部分,字符串池是用字符串填充的运行时缓存.
>并且根据Java语言规范jls-3.10.5,引用字符串文字并不直接引用常量池;当且仅当字符串池中没有值时,字符文字才会从常量池填充字符串池.

也就是说,从源文件到运行时的String对象的生命周期如下:

>在编译时由编译器放入常量池并存储在生成的类文件中(每个类文件有一个常量池)
> JVM在类加载时加载常量池
>从常量池创建的字符串在运行时被添加到字符串池中,因为调用实习生(如果已经存在等效字符串,如果已经存在字符串,那么将使用字符串池中的字符串)JVM Spec 5.1 – The Run-Time Constant Pool.
> intern可以通过手动调用intern()显式发生,也可以通过引用字符串文字(如“abc”jls-3.10.5)隐式发生.

以下两个代码片段之间的行为差??异是由于在通过字符串文字发生对内部的隐式调用之前显式调用intern()引起的.

为清楚起见,这里是对这个答案的评论中讨论的两种行为的贯彻:

String c = "qwe";   // string literal qwe goes into runtime cache
    String d = c.substring(1); // runtime string "we" is created
    d.intern();         // intern "we"; it has not been seen 
                        // yet so this version goes into the cache
    String e = "we";    // now we see the string literal,but
                        // a value is already in the cache and so 
                        // the same instance as d is returned 
                        // (see ref below)

    System.out.println( e == d );  // returns true

以下是在使用字符串文字后我们实习的情况:

String c = "qwe";   // string literal qwe goes into runtime cache
    String d = c.substring(1); // runtime string "we" is created
    String e = "we";    // now we see the string literal,this time
                        // a value is NOT already in the cache and so 
                        // the string literal creates an object and
                        // places it into the cache
    d.intern();         // has no effect - a value already exists
                        // in the cache,and so it will return e

    System.out.println( e == d );  // returns false
    System.out.println( e == d.intern() );  // returns true
    System.out.println( e == d );  // still returns false

下面是JLS的关键部分,声明实际上是为字符串文字调用实习生.

Moreover,a string literal always refers to the same instance of class String. This is because string literals – or,more generally,strings that are the values of constant expressions (§15.28) – are “interned” so as to share unique instances,using the method String.intern.

JVM规范涵盖了从类文件加载的常量池的运行时表示的详细信息,并且它与实习生交互.

If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure,then the result of string literal derivation is a reference to that same instance of class String. .

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读