字符串常量池-常量项(cp_info)结构
CONSTANT_String_info{ u1 tag=8; u2 string_index;//存放 CONSTANT_Utf8_info 指针 } CONSTANT_Utf8_info{ u1 tag=1; u2 length;//字节数组长度 u1 bytes[length];//使用utf8编码后的字节数组 }
案例1
public class StringDemo { private String s1="字符串S1"; }
javac StringDemo.java
javap -verbose StringDemo.class
#15:CONSTANT_Utf8_info结构体
CONSTANT_Utf8_info{ u1 tag=1; u2 length;//字节数组长度 u1 bytes[length];//使用utf8编码后的字节数组 }
#2:CONSTANT_String_info结构体
CONSTANT_String_info{ u1 tag=8; u2 string_index;//存放#15 }
案例2
public class StringDemo { private String s1="MyStr1"; private String s2="MyStr1"; }
javac StringDemo.java
javap -verbose StringDemo.class
案例3
public class StringDemo { private String s1= new String("MyStr1"); }
案例4
public class StringDemo20 { private String s1="MyStr1"; private String s2="MyStr1"; private String s3="My"+"Str1"; private String s01="My"; private String s02="Str1"; private String s4 = s01+s02; private String s5 = s4.intern(); private static String str1="MyStr1"; private static String str2="MyStr1"; private static String str3="My"+"Str1"; private static String str01="My"; private static String str02="Str1"; private static String str4 = str01+str02; private static String str5 = str4.intern(); private static final String fstr1="MyStr1"; private static final String fstr2="MyStr1"; private static final String fstr3="My"+"Str1"; private static final String fstr01="My"; private static final String fstr02="Str1"; private static final String fstr4 = fstr01+fstr02; private static final String fstr5 = fstr4.intern(); class InnerDemo{ private String s1="MyStr1"; private String s2="MyStr1"; private String s3="My"+"Str1"; private String s01="My"; private String s02="Str1"; private String s4 = s01+s02; private String s5 = s4.intern(); private static final String ifstr1="MyStr1"; private static final String ifstr2="MyStr1"; private static final String ifstr3="My"+"Str1"; private static final String ifstr01="My"; private static final String ifstr02="Str1"; private static final String ifstr4 = ifstr01+ifstr02; //private static final String ifstr5 = ifstr4.intern(); } public static void main(String[] args){ StringDemo20 stringDemo = new StringDemo20(); System.out.println("s1==s2:"+(stringDemo.s1==stringDemo.s2)); System.out.println("s1==s3:"+(stringDemo.s1==stringDemo.s3)); System.out.println("s1==s4:"+(stringDemo.s1==stringDemo.s4));//false System.out.println("s1==s5:"+(stringDemo.s1==stringDemo.s5)); System.out.println("s1==str1:"+(stringDemo.s1==StringDemo20.str1)); System.out.println("s1==str3:"+(stringDemo.s1==StringDemo20.str3)); System.out.println("s1==str4:"+(stringDemo.s1==StringDemo20.str4));//false System.out.println("s1==str5:"+(stringDemo.s1==StringDemo20.str5)); System.out.println("s1==fstr1:"+(stringDemo.s1==StringDemo20.fstr1)); System.out.println("s1==fstr3:"+(stringDemo.s1==StringDemo20.fstr3)); System.out.println("s1==fstr4:"+(stringDemo.s1==StringDemo20.fstr4)); System.out.println("s1==fstr5:"+(stringDemo.s1==StringDemo20.fstr5)); System.out.println("s1==innerdemo.fstr1:"+(stringDemo.s1==InnerDemo.ifstr1)); System.out.println("s1==innerdemo.fstr3:"+(stringDemo.s1==InnerDemo.ifstr3)); System.out.println("s1==innerdemo.fstr4:"+(stringDemo.s1==InnerDemo.ifstr4)); } }
javap -verbose StringDemo20.class >d:/1.txt
可以看到 str1、str2、str3、str5都是 ldc #22。
可以看到 str1、str2、str3都是 ldc #22。s5在运行期间,放入运行时常量池。
推荐:
http://www.ciaoshen.com/2016/07/29/string/
http://tangxman.github.io/2015/07/27/the-difference-of-java-string-pool/
Thinking in Java 读书笔记:第十三章 - 字符串
https://www.zhihu.com/question/29884421/answer/113785601
http://rednaxelafx.iteye.com/blog/774673
http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html