jdk1.8下string.intern()分析

一. String.intern()分析

 判断这个常量是否存在于常量池。
  如果存在
   判断存在内容是引用还是常量,
    如果是引用,
     返回引用地址指向堆空间对象,
    如果是常量,
     直接返回常量池常量
  如果不存在,
   将当前对象引用复制到常量池,并且返回的是当前对象的引用

二. 创建字符串分析

1. 只在常量池上创建常量

String a1 = “AA”;

2. 只在堆上创建对象

String a2 = new String(“A”) + new String(“A”);

3. 在堆上创建对象,在常量池上创建常量

String a3 = new String(“AA”);

4. 在堆上创建对象,在常量池上创建引用

1
2
3
String a4 = new String("A") + new String("A");//只在堆上创建对象AA

a4.intern();//将该对象AA的引用保存到常量池上

5. 在堆上创建对象,在常量池上创建常量,在常量池上创建引用(不可能

1
2
3
4
5
6
7
String a5 = new String("A") + new String("A");//只在堆上创建对象

a5.intern();//在常量池上创建引用

String a6 = "AA";//此时不会再在常量池上创建常量AA,而是将a5的引用返回给a6

System.out.println(a5 == a6); //true

三. 总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
         String aa = "AA";//设置常量AA到常量池
String bb = "BB";//设置常量BB到常量池
String ccdd = "CC"+"DD";//设置常量CCDD到常量池
String neeff = new String("EE")+new String("FF");//设置EE和FF到常量池。并且添加EE、FF和EEFF对象到堆
String aabb = aa+bb;//添加AABB对象到堆
String gghh = "GG"+new String("HH");//设置GG和HH常量到常量池,设置HH和GGHH对象到堆
// aa.intern();//啥事都不做,返回AA常量
// ccdd.intern();//啥事都不做,返回CCDD常量
// neeff.intern();//添加EEFF对象的引用到常量池,并返回EEFF对象
// aabb.intern();//添加AABB对象的引用到常量池,并返回AABB对象
// gghh.intern();//添加GGHH对象的引用到常量池,并返回GGHH对象
System.out.println(aa.intern()==aa); //true
System.out.println(neeff.intern()=="EEFF");//true
System.out.println("EEFF"==neeff);//true
String nccdd = new String("CCDD");
System.out.println(ccdd==nccdd);//false
System.out.println(ccdd==nccdd.intern());//true
System.out.println(aabb.intern()==aabb);//true
System.out.println(gghh==gghh.intern());//true