String常量池

常量池:在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量.

代码清单1-1

String s0=”kvill”;  
String s1=”kvill”;  
String s2=”kv” + “ill”;  
System.out.println( s0==s1 );  
System.out.println( s0==s2 ); 

代码清单1-1中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。所以我们得出s0==s1==s2; 用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

代码清单1-2

public class StringPoolTest {
		  
    public static void main(String[] args) {  
        String str = "abc";  
        char[] array = {'a', 'b', 'c'};  
        String str2 = new String(array);  
        //使用intern()将str2字符串内容放入常量池  
        str2 = str2.intern();  
        //这个比较用来说明字符串字面常量和我们使用intern处理后的字符串是在同一个地方  
        System.out.println(str == str2);  
        //那好,下面我们就拼命的intern吧  
        ArrayList<String> list = new ArrayList<String>();  
        for (int i = 0; i < 10000000; i++) {  
            String temp = String.valueOf(i).intern();  
            list.add(temp);  
        }  
        System.out.println(list.size());
    }  
}
代码清单1-2在JDK7下的运行结果

true
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Unknown Source)
	at java.util.Arrays.copyOf(Unknown Source)
	at java.util.ArrayList.grow(Unknown Source)
	at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)
	at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
	at java.util.ArrayList.add(Unknown Source)
	at cn.com.test.p201612.StringPoolTest.main(StringPoolTest.java:19)

代码清单1-2在JDK6下的运行结果

true
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
	at java.lang.String.intern(Native Method)
	at cn.com.test.p201612.StringPoolTest.main(StringPoolTest.java:18)



原因是Jdk6版本中常量也是放在Perm区中的,在 jdk7 的版本中,字符串常量池已经从Perm区移到正常的Java Heap区域了。为什么要移动,Perm 区域太小是一个主要原因,当然据消息称jdk8已经直接取消了Perm区域,而新建立了一个元区域。


结合代码及图来看一下:

public static void main(String[] args) {
    String s = new String("1");
    String s2 = "1";
    s.intern();
    System.out.println(s == s2);
 
    String s3 = new String("1") + new String("1");
    String s4 = "11";
    s3.intern();
    System.out.println(s3 == s4);
}

jdk6中的解释:



jdk7中的解释






参考资料:

http://www.cnblogs.com/wxgblogs/p/5635099.html











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值