java8 常量池_Java 8 常量池?

Java 对于基本类型和 String 采用池化的享元模式,将其放在常量池中,提高运行程序速度,更节省内存

String 有两种方式放入常量池中String ab = "ab" 定义字面字符串

ab.intern() 该方法的解释, 若在常量池中,取引用,不在就加入常量池取引用;* When the intern method is invoked, if the pool already contains a

* string equal to this {@code String} object as determined by

* the {@link #equals(Object)} method, then the string from the pool is

* returned. Otherwise, this {@code String} object is added to the

* pool and a reference to this {@code String} object is returned.

实验1:

String c = new String("ceudcnfsalncfw");

c.intern();

String d = "ceudcnfsalncfw";

System.out.println(c==d);//false 第一步

String ab = new String("dnsdfnjew")+new String("dnjsfne");

ab.intern();

String cd = "dnsdfnjewdnjsfne";

System.out.println(ab==cd);//true 第二步

实验1分析:new String 首先会在堆里创建一个 String 对象,然后常量池没有就会添加进去;所以 c 是 new 的引用,d 是常量池里的引用

ab 是堆里的一份引用,此时 "dnsdfnjewdnjsfne" 是不在常量池里的 (第一步的 new 会直接创建在常量池里, 而这里是由 StringBuilder 拼接而成的, 不会直接添加到常量池),另外 java 8 里常量池不用单独再存储一份对象,可以直接存储堆中的引用,所以 ab 和 cd 引用的是同一个对象;

实验2:

运行了一段代码,然后出现了?? (不认识 python??)

String str3 = new StringBuffer("jav").append("a").toString();

System.out.println(str3.intern() == str3);//false 1 String str4 = new StringBuffer("pyth").append("on").toString();

System.out.println(str4.intern() == str4);//true 2

然后换了 StringBuilder 实现??

String str1 = new StringBuilder("ja").append("va").toString();

System.out.println(str1.intern() == str1);//false 3 String str4 = new StringBuilder("pyth").append("on").toString();

System.out.println(str4.intern() == str4);//true 4

再然后??

String ab = new String("dnsdfnjew")+new String("dnjsfne");

ab.intern();

String cd = "dnsdfnjewdnjsfne";

System.out.println(ab==cd);// true 5

String ab2 = new String("ja")+new String("va");

ab2.intern();

String cd2 = "java";

System.out.println(ab2==cd2);//false 6

推测: “java” 默认加在常量池里?

2 和 4 的分析应该和实验 1 的第二步一样的; 常量池里存储着堆里的引用

1,3,6 都是 false; 推测是根加载器主动将 "java" 字符串添加到常量池里,跟堆里的“java”内存地址是不一样的,所以引用指向堆和常量池是不相同的;

那么哪些字符串会被 JVM 主动添加到常量池?

JDK 8 跑的实验,可以试试;

参考

你可能感兴趣的:(java8,常量池)