都说字符串无论在哪里都是非常重要的存在,所以这个问题希望的到解答,我在别的人的博客上看到了这个我觉得说的应该是对的,摘抄如下:
在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的理解错了,还是我哪里理解错了?谢谢帮忙