String中的intern方法
一.intern方法的用途
关于字符串String中的intern方法,是当常量池中不存在"abc"这个字符串的引用,将这个对象的引用加入常量池,返回这个对象的引用,当常量池中存在"abc"这个字符串的引用,返回这个对象的引用。
java中获取String常量池中常量有两种方法:一个是通过双引号定义字符串例如:String S = “1”;一个是String的intern方法。
二.intern使用示例
在jdk1.8下
public class Main {
public static void main(String[] args){
String s1 = new String("1");
String s2 = "1";
System.out.println(s1 == s2);
String s3 = new String("1");
System.out.println(s1 == s3);
String s4 = new String("2").intern();
String s5 = "2";
System.out.println(s4 == s5);
}
}
结果为:
false
false
true
Process finished with exit code 0
在JDK1.6中结果是会有所不同的,是在字符串拼接的情况下有所不同:
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
jdk7 下是:false true
因为在1.7的时候,常量池是被移到堆中,1.6的时候再方法区(永久代)中。由于String大量的使用导致永久代经常发生OutOfMemoryError,所以将StringPool搬到heap中。
在1.6的时候,拿堆中对象地址与方法区中对象地址比肯定是不一样的,这是两个对象。
但是在1.7的时候,常量池不在方法区了,因此做了调整:常量池中不需要再存储一份对象了,可以直接存储堆中的引用。这份引用指向s3引用的对象。 也就是说引用地址是相同的。
三.intern的使用技巧
适当的使用可以减少内存的消耗,每次new String都会产生一个新的对象,如果适当的使用
String s = new String("1").intern();
能够适当的获取常量池的常量。
由于JDK1.6中String Pool大小限制在1009,底层是hash表加上链表组成,如果过度的使用,会导致链表过长从而导致速度变慢,所以
不是每个场景都适合使用intern方法(JDK1.7之后可以通过-XX:StringTableSize=99991设定hash表的大小)
https://www.cnblogs.com/feizhai/p/10196955.html