public class HelloWorld {public static void main(String[] args) {String s1 = new String("hello") + new String("world");s1.intern();String s2 = "helloworld";System.out.println(s1==s2);}
}
jdk1.6输出:false
jdk1.8输出为:true
在 JDK 6 中, intern() 方法会把首次遇到的字符串实例复制到永久代的字符串常量池
中存储
在 JDK 8中,intern()只需要在常量池里记录一下首次出现的实例引用即可
在JDK 8中,在调用后发现StringTable中没有所对应的字符串。
String s1 = new String("hello") + new String("world");
这句代码会在堆中new一个String对象(其实并没有这么简单,后面讲)
s1.intern();
s1调用了intern方法,然后发现在StringTable中并没有所对应的字符串,
那么jvm就会在StringTable中放入一个地址,这个地址指向s1所new的String对象。
String s2 = "helloworld";
jvm发现在StringTable中已经存在指向"helloworld"的地址了,就会把StringTable中的
地址给s2。此时s1和s2都指向这个地址。所以是同一个对象。于是返回了true
String s1 = new String("hello") + new String("world");
这句代码会在堆中new一个String对象(其实并没有这么简单,后面讲)
s1.intern();
s1调用了intern方法,然后发现在StringTable中并没有所对应的字符串,
那么jvm就会在StringTable中放入一个地址,这个地址指向s1所new的String对象。
String s2 = "helloworld";
jvm发现在StringTable中已经存在指向"helloworld"的地址了,就会把StringTable中的
地址给s2。此时s1和s2都指向这个地址。所以是同一个对象。于是返回了true
public class HelloWorld {public static void main(String[] args) {String s1 = new String("hello") + new String("world");String s2 = "helloworld";s1.intern();System.out.println(s1==s2);}
}
jdk1.8输出为:false
方法区是《Java虚拟机规范》中规定的一个内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。
元空间是方法区的实现。方法区的实现,JDK1.7之前是永久代,JDK1.8之后是元空间。
永久代在物理上是堆的一部分,元空间内存是操作系统本地内存。
Jdk1.7之前类的元数据、静态变量、字符串常量池都是在永久代
jdk1.8之后类的元数据在本地内存,静态变量和字符串常量在堆内存,相当于方法区只有类的元数据