StringTable常量池

编程

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

}

}

以上是 StringTable常量池 的全部内容, 来源链接: utcz.com/z/516131.html

回到顶部