字面值字符串是在类加载的时候还是运行的时候在常量池里创建对象? 2C

都说字符串无论在哪里都是非常重要的存在,所以这个问题希望的到解答,我在别的人的博客上看到了这个我觉得说的应该是对的,摘抄如下:

在Java源代码中的每一个字面值字符串,都会在编译成class文件阶段,形成标志号为8(CONSTANT_String_info)的常量表 。当JVM加载 class文件的时候,会为对应的常量池建立一个内存数据结构,并存放在方法区中。同时JVM会自动为CONSTANT_String_info常量表中 的字符串常量的字面值在堆中创建新的String对象(intern字符串对象 ,又叫拘留字符串对象)。然后把CONSTANT_String_info常量表的入口地址转变成这个堆中String对象的直接地址(常量池解析)。

但是我在写的小Demo的结果好像个这个并不符合代码如下:

Demo1:

        String str2 = new String("abc");         
        String str1 = new String("abc");   

    String  str3=str1+str2;
    String str4=str3.intern();
    String str7="abcabc";

    System.out.println(str4==str3);     
    System.out.println(str7==str4);

    /**

     * output:

     * true

     * true

     */

Demo2:

        String str2 = new String("abc");         
    String str1 = new String("abc");  

    String  str3=str1+str2;
    String str7="abcabc";
    String str4=str3.intern();

    System.out.println(str4==str3);     
        System.out.println(str7==str4);

    /**

     * output:

     * false

     * true

     */

如果字面值字符串是在类加载的时候在常量池内创建“abcabc”字符串,那么我感觉两次的答案应该一样 既然不一样,我只能这样解释通

Demo1中str3创建一个对象但是应为是字符串连接对象所以不会调用自身的intern()方法也就不会再常量池里放入“abcabc”, String str4=str3.intern();这句话吧str3的引用放入常量池, String str7="abcabc";这句话则是从常量池里拿所以是truetrue.

Demo2中 String str3=str1+str2;同上, String str7="abcabc"发现常量池里面没有所以在常量池里创建“abcabc”, String str4=str3.intern();则是从常量池里得到“abcabc”所以是false true

以上两个Demo可以显示字面值字符串是在运行的时候创建的否则都应该是 false true这个答案

所以我想知道字面值字符串是在类加载的时候还是运行的时候在常量池里创建对象?

是我看到的摘抄错了还是我对于小Demo的理解错了,还是我哪里理解错了?谢谢帮忙

2个回答

我是学C、C++、和汇编的。只能用底层知识来解释这一块。当进行源文件的编译的过程中。编译器会将字符串提取出来放在一个理解上的“公共”段中
,当后续要用到这些字符串是,编译器直接将其转化为相应的字符串所在段具体的地址,直接穿进去供函数使用就OK了。图片说明图片说明
建议你去了解一下底层有关内存知识后。这块就很好解释了。

好尴尬、有个图传错了不知道怎么改了,刚转的msdn。
补图图片说明

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问