StringTable常量池

混江龙づ霸主 提交于 2020-05-04 19:14:27

package com.jvm;

import org.junit.Test;

/**
 * 常量池StringTable的详解
 * 可以使用该命令查看,当前类的字节码常量池信息
 * javap -v StringTableTest.class
 *
 * @author shiye
 * @date 2020-05-04 13:13
 */
public class StringTableTest {

    @Test
    public void test1() {
        String s1 = "a";//放到常量池中
        String s2 = "b";//放到常量池中
        String s3 = "ab"; //放到常量池中

        /**
         * 首先创建一个StringBuilder对象 然后从常量池中获取一个"a",然后再从常量池中获取一个"b"对象
         * 然后再在堆中创建一个 new String("ab") 对象
         * new StringBuilder().append("a").append("b").toString();
         * --> toString()方法就是 new String("ab");
         */
        String s4 = s1 + s2;   //放到堆中
        System.out.println(s3 == s4); //一个在堆中,一个再常量池中 false

        /**
         * ldc    #4   // String ab 直接从常量池中获取 "ab"
         * 这是javac在代码编译时的优化操作
         * 会把 "a"+"b" 优化成 "ab",然后从常量池中查找
         */
        String s5 = "a" + "b"; //放到常量池中
        System.out.println(s3 == s5); // true
    }


    /**
     * 首先常量池中有 ["a","b"] 俩个对象
     * s.intern() 会把堆中创建的 "ab" 对象放到常量池中,如果常量池中有"ab"了 ,
     * 则不会放到常量池中,但是一定会返回常量池中的对象
     * <p>
     * 对比:test2和test3
     */
    @Test
    public void test2() {
        String s = new String("a") + new String("b");
        String s2 = s.intern();
        System.out.println(s2 == "ab");// true
        System.out.println(s == "ab");//true
    }

    @Test
    public void test3() {
        String x = "ab"; //常量已经有了“ab” 就不会再放进去了
        String s = new String("a") + new String("b");
        String s2 = s.intern();
        System.out.println(s2 == "ab");// true
        System.out.println(s == "ab");//false
    }

}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!