JAVA字符串常量池你弄懂了吗?看看这个10个问题你能不能回答正确

JAVA字符串常量池你弄懂了吗?看看这个10个问题你能不能回答正确

在这里插入图片描述

/**
 * @author humorchen
 * @date 2021/12/28 10:43
 */
public static void main(String[] args) throws InterruptedException {
        String s = new String("1");
        String intern = s.intern();
        String s1 = "1";
        String s2 = new String("1");
        System.out.println("s == intern \t" + (s == intern));
        System.out.println("s == s1 \t" + (s == s1));
        System.out.println("intern == s1 \t" + (intern == s1));
        System.out.println("s == s2 \t" + (s == s2));
        System.out.println("s.intern() == s2.intern() \t" + (s.intern() == s2.intern()));
        String s3 = new String("1") + new String("1");
        String s4 = "11";
        System.out.println("s3 == s4 \t" + (s3 == s4));
        System.out.println("s3.intern() == s4 \t" + (s3.intern() == s4));
        String s5 = new String("2") + new String("2");
        s5.intern();
        String s6 = "22";
        System.out.println("s5 == s6 \t" + (s5 == s6));
        System.out.println("s5.intern() == s6 \t" + (s5.intern() == s6));
        String s7 = s5.intern();
        System.out.println("s5 == s7 \t" + (s5 == s7));
    }

请开始你的代码阅读和思考答案下面将贴出答案,先思考好再看答案。

在这里插入图片描述

对完答案之后,很多人应该就懵懵的了吧。下面我来解答一下

public static void main(String[] args) throws InterruptedException {
        String s = new String("1");
        /**
         * 第一步,"1",在常量池里创建一个"1"字符串对象,假设内存地址为 pool-1
         * 第二步,new String在堆中创建一个String对象,字符数组为['1'],假设内存地址为 heep-s
         * 第三步,创建变量s,类型String,引用第二步在堆中创建的对象的地址,也就是引用的 heep-s
         */
        String intern = s.intern();
        /**
         * 第一步,s.intern(),在常量池查找有没有s这个字符串,如果有直接返回常量池里这个字符串,如果没有则将该字符串加入常量池,并返回该字符串,发现有,地址为 pool-1
         * 第二步,创建变量intern,类型String,引用常量池中这个字符串的地址,也就是引用的 pool-1
         */
        String s1 = "1";
        /**
         * 第一步,"1",发现常量池中已经有"1"了,返回常量池中“1”这个字符串对象,地址为 pool-1
         * 第二步,创建变量s1,类型String,引用常量池当中这个字符串的地址,也就是 pool-1
         */
        String s2 = new String("1");
        /**
         * 第一步,"1",查常量池里有没有,发现有"1",地址为 pool-1
         * 第二步,new String,在堆当中创建一个String对象,字符数组为['1'],假设内存地址为 heap-s2
         */
        System.out.println("s == intern \t" + (s == intern));
        /**
         * s = heep-s
         * intern = pool-1
         * 因此返回false
         */
        System.out.println("s == s1 \t" + (s == s1));
        /**
         * s = heep-s
         * s1 = pool-1
         * 因此返回false
         */
        System.out.println("intern == s1 \t" + (intern == s1));
        /**
         * intern = pool-1
         * s1 = pool-1
         * 因此返回true
         */
        System.out.println("s == s2 \t" + (s == s2));
        /**
         * s = heep-s
         * s2 = heep-s2
         * 因此返回false
         */
        System.out.println("s.intern() == s2.intern() \t" + (s.intern() == s2.intern()));
        /**
         * s.intern = pool-1
         * s2.intern = pool-1
         * 因此返回true
         */
        String s3 = new String("1") + new String("1");
        /**
         * 第一步,"1",发现常量池里已经有了,地址为 pool-1
         * 第二步,new String,创建了两个匿名的String对象,每个自己的字符数组都是['1'],这两个匿名对象后续在垃圾回收的时候会被回收的
         * 第三步,创建一个StringBuilder,append("1"),append("1"),字符数组为['1','1'],也就是“11”,append完毕走stringBuilder.toString返回在堆里创建的String对象,假设内存地址为 heap-s3
         * 第四步,创建变量s3,类型String,引用地址为 heap-s3
         */
        String s4 = "11";
        /**
         * 第一步,"11",发现常量池里没有,加入常量池,假设地址为 pool-11
         * 第二步,创建一个变量s4,类型String,引用地址 pool-11
         */
        System.out.println("s3 == s4 \t" + (s3 == s4));
        /**
         * s3 = heap-s3
         * s4 = pool-11
         * 因此返回false
         */
        System.out.println("s3.intern() == s4 \t" + (s3.intern() == s4));
        /**
         * s3.intern = "11"在常量池里的地址,也就是等于 pool-11
         * s4 = pool-11
         * 因此返回true
         */
        String s5 = new String("2") + new String("2");
        /**
         * 第一步,"2",入常量池,假设地址为 pool-2
         * 第二步,new String,创建两个匿名对象在堆里,后续垃圾回收会回收掉的
         * 第三步,组装起来,创建一个StringBuilder,将两个String append进去,最后调用这个StringBuilder的toString返回组装好的String对象(堆里),内部的字符数组为['2','2'],假设内存地址为 heap-s5
         * 第四步,创建变量s5,类型String,引用地址为 heap-s5
         */
        s5.intern();
        /**
         * 第一步,s5.intern(),将s5的字符串"22"放入字符串常量池,这个时候常量池里没有"22",因此在常量池中创建了一个字符串"22"的对象,引用地址为s5,并返回s5的地址 heap-s5
         */
        String s6 = "22";
        /**
         * 第一步,"22",检查常量池发现已经有了"22",因此返回内存地址 heap-s5
         * 第二步,创建变量s6,类型String,引用地址为 heap-s5
         */
        System.out.println("s5 == s6 \t" + (s5 == s6));
        /**
         * s5 = heap-s5
         * s6 = heap-s5
         * 因此返回true
         */
        System.out.println("s5.intern() == s6 \t" + (s5.intern() == s6));
        /**
         * s5.intern =s5这个字符串在常量池里的地址 = heap-s5
         * s6 = heap-s5
         */
        String s7 = s5.intern();
        /**
         * 第一步,s5.intern(),检查s5的字符串是不是在常量池,发现已经在了,返回常量池里这个字符串“22”的引用地址 heap-s5
         * 第二步,定义变量s7,类型String,引用地址为 heap-s5
         */
        System.out.println("s5 == s7 \t" + (s5 == s7));
        /**
         * s5 = heap-s5
         * s7 = heap-s5
         * 因此返回true
         */
    }
posted @ 2022-01-06 13:06  HumorChen99  阅读(0)  评论(0编辑  收藏  举报  来源