intern方法的理解
目录结构如下
1. intern方法的概述及理论
2. intern的实际作用
3. 用代码演示其作用
## 1. intern方法的概述及理论 ##
首先对象会在字符串常量池查找是否有对应的字符串常量(用equals(object)比较)。如果有对应的字符串常量,则返回该字符串常量。如果没有,则将字符串添加进来并指向该对象。
## 2. intern的实际作用 ##
在于重复利用String对象,以节省内存的消耗
## 3. 用代码演示其作用 ##
先用代码演示一篇证明intern是否会重用String对象。
static final int MAX = 100000;
static final String[] arr = new String[MAX];
public static void main(String[] args) throws Exception {
//为长度为10的Integer数组随机赋值
Integer[] sample = new Integer[10];
Random random = new Random(1000);
for (int i = 0; i < sample.length; i++) {
sample[i] = random.nextInt();
}
//记录程序开始时间
long t = System.currentTimeMillis();
//使用/不使用intern方法为10万个String赋值,值来自于Integer数组的10个数
for (int i = 0; i < MAX; i++) {
arr[i] = new String(String.valueOf(sample[i % sample.length]));
//arr[i] = new String(String.valueOf(sample[i % sample.length])).intern();
}
System.out.println((System.currentTimeMillis() - t) + "ms");
System.gc();
}
这里的代码主要是用来看有无intern对执行时间跟生成对象数的影响。
从上面的结果可以看出,无intern方法时创建的对象为101762个,而有intern方法时创建的只有1772个。证明intern是重用了String对象,节省了内存。
接下来分析intern与常量池(方法区)、堆之间的关系
先利用网上流传的例子。
String s = new String("1");
s.intern();
String s2 = "1";
System.out.println(s == s2);
String s3 = new String("1") + new String("1");
s3.intern();
String s4 = "11";
System.out.println(s3 == s4);
结果为
false
true
分析:
已经在常量池中
1.String s = new String(“1”); 生成了在堆空间中对象以及常量池中的“1”
2.s.intern()时发现“1”已经在常量池了
3.String s2 = “1”;即s2引用的是常量池中的“1”;
4.s引用的是堆空间里的那个指向常量“1”的对象,而s2是指向常量1的对象。两者对象不同
不在常量池中
1.String s3 = new String(“1”) + new String(“1”); 创建一个常量“1”,两个String对象指向该常量。
2.s3.intern(); 发现常量池中无“11”,则该常量引用s3对象
3.String s4 = “11”; s4引用的是s3
4.System.out.println(s3 == s4); s3==s4,所以为true
总结:
1、对jvm的内存区域不太了解。