关于字符串在常量池中中的存储问题

关于字符串在常量池中中的存储问题

package com.xwl;
/**
 * 关于常量池的问题
 * @author Administrator
 * 字符串常量池
 */
public class AboutInterview {
    public static void main(String[] args) {
         String s1 = "hello";
         String s2 = "hello";
         String s3 = "he" + "llo";
         String s4 = "hel" + new String("lo");
         String s5 = new String("hello");
         String s6 = s5.intern();
         String s7 = "h";
         String s8 = "ello";
         String s9 = s7 + s8;
         System.out.println(s1==s2);//true  s1创建后在串池中,s2创建时候发现已经有,这返回s1的地址 因此相等
         System.out.println(s1==s3);//true  s3字符串拼接后就是s1 jvm在编译期间就已经对它进行优化   因此相等
         System.out.println(s1==s4);//false
         /**
          * s4中的new String("lo")生成了两个对象,"lo","new String("lo")",
          *"lo"存在字符串常量池,"new String("lo")"存在堆中,
          *String s4 = "hel" + new String("lo")实质上是两个对象的相加,
          *编译器不会进行优化,相加的结果存在堆中,而s1存在字符串常量池中,当然不相等。
          */
         System.out.println(s1==s9);//false
         System.out.println(s4==s5);//false
         System.out.println(s1==s6);//true
         System.out.println("-----------------------------------");
         String c1 = new String("hello");
         String c2 = "hello";
         String intern1 = c1.intern();
         System.out.println(intern1 == c2);
         String c3 = new String("hello") + new String("hello");
         String c4 = "hellohello";
         String intern3 = c3.intern();
         System.out.println(intern3 == c4); 
         /**
          * jdk1.6下字符串常量池是在永久区中,是与堆完全独立的两个空间,
          * c1指向堆中的内容,c2指向字符串常量池中的内容,两者当然不一样,
          * c1.intern1()将字面量加入字符串常量池中,
          * 由于字符串常量池中已经存在该字面量,所以返回该字面量的唯一引用,intern1==c2就输出true。
          * jdk1.7,1.8下字符串常量池已经转移到堆中了,是堆中的一部分内容,
          * jvm设计人员对intern()进行了一些修改.
          * 当执行c3.intern()时,jvm不再把s3对应的字面量复制一份到字符串常量池中,
          * 而是在字符串常量池中存储一份s3的引用,这个引用指向堆中的字面量,
          * 当运行到String c4 = "hellohello"时,
          * 发现字符串常量池已经存在一个指向堆中该字面量的引用,则返回这个引用,而这个引用就是c3。所以c3==c4输出true。
          */
         System.out.println("---------------------");
         String d1 = new String("hello");
         String d2 = "hello";
         String inter1 = d1.intern();
         System.out.println(d1 == d2);
         String d3 = new String("hello") + new String("hello");
         String d4 = "hellohello";
         String inter3 = d3.intern();
         System.out.println(d3 == d4);
         /**
          * s3指向堆内容,接着s4="hellohello"发现字符串常量池中没有该字面量,创建并返回该引用。
          * s3,s4一个在堆,一个在字符串常量池,是两个独立的引用,所以s3==s4输出false。
          */    
        }
}

你可能感兴趣的:(java基础,jvm,虚拟机)