1.方法intern()为java内部方法,如下
public native String intern();
native方法为通过jvm进行运行,jdk8中隐藏了该方法的具体处理方法。
2.作用:该方法注释为
3.测试代码一
public static void main(String[] args) { String s1 = new String("1"); s1.intern(); String s2 = "1"; System.out.println(s1 == s2); String s3 = new String("1") + new String("1"); s3.intern(); String s4 = "11"; System.out.println(s3 == s4); }
结果:
jdk6环境下:
false false
jdk8环境下:
false true
原因分析:
1)jdk6的虚拟机结构中常量池主要是在Perm中,即内存模型为对象存放到java堆区(heap)中,而常量池主要是在java方法区。属于不同的两个区域。
字符串的初始化中,new时会创建一个对象放在java堆中,而通过引号创建则会在常量池中创建常量,两个区域是隔绝的,因此即使intern之后比较引用的话也不会是相同的。
2)jdk7之后由于之前Perm的大小只有4M,已经无法满足项目的发展,因此取消了Perm的限制,而是移动到了堆区,jdk8更是取消了Perm区。
对于上面代码,s1创建的时候,生成了一个对象和一个对象的值,因此s1对应的是对象的引用,s2是对应的常量的引用。
s3初始化的时候对于“11”来说只有一个对象,当调用intern的时候,由于没有该常量,因此jdk7之后会生成一个指向对象的引用存放到常量中。而当s4初始化之后,s4也直接为常量中的对象的引用,因此引用值比较之后为true。
JDK源码学习(2)-String.intern()方法详解
原文地址:http://yinyueml.blog.51cto.com/4841237/1768693