常量池学习总结

常量池

一、Class常量池
存放Class文件编译期生成的各种字面量符号引用两类常量。
字面量就是指由字母、数字等构成的字符串或者数值常量,字面量只能是右值(等号右边的值)。
符号引用是编译原理中的概念,是相对于直接引用来说的。主要包括以下三类常量:
类和接口的全限定名
字段的名称和描述符
方法的名称和描述符

package com.jvm;

//这个例子中1和1234都是字面量。
//在编译期,a和b就是符号引用,类的全限定名com.jvm.Test、方法名init()也都是符号引用
public class Test {
	private static viod init() {
    	int a = 1;
		String b = "1234";
	}
}

二、运行时常量池
Class常量池在运行阶段就会变成运行时常量池,对应的符号引用会变成直接引用,也就是动态链接,例如,init()这个符号引用在运行时就会被转变为init()方法具体代码的内存地址
三、字符串常量池
JDK1.6及以前和1.7常量池位置不一样:
1.6及以前:有永久代, 运行时常量池在永久代,运行时常量池包含字符串常量池
1.7:有永久代,但已经逐步“去永久代”,字符串常量池从永久代里的运行时常量池分离到堆里
1.8及之后: 无永久代,运行时常量池在元空间,字符串常量池里依然在堆里
字符串操作的对象创建方式(JDK1.7 及以上版本):
1、直接赋值:

String s = "hello";// s会指向常量池中的引用

因为hello是一个字面量,JVM会先去常量池通过equals(key)方法判断是否有相同的对象,有就返回引用,没有就先创建再返回引用

2、new String():

String s = new String("hello")//s会指向内存中的引用

这种方式会在常量池和对内存中都创建这个对象,最后返回的是堆内存中的对象引用

3、intern方法:

String s1 = new String("zhuge");   
String s2 = s1.intern();//s2会指向zhuge字符串的常量池引用
System.out.println(s1 == s2);  //false

这个方法是native方法,如果常量池中已经有一个等于此String对象的字符串,则返回池中引用,没有的话会返回s1对象的引用

设计原理:
字符串常量池的底层类似一个 HashTable,本质上存储的是字符串对象的引用,实际的对象还是在堆中(HashTable是k-v结构,k存的是对象的堆引用,v存的是具体的对象地址),因为JDK版本不同对象存储位置也不同,所以对象创建也不一样:

String s1 = new String("he") + new String("llo");
String s2 = s1.intern();
System.out.println(s1 == s2);//会输出什么?

在JDK1.6中,首先在局部变量表中会有s1,s2两个对象,并且在永久代的常量池中会创建两个对象,一个he一个llo,两个new操作也会在堆中创建两个对象,s1中有拼接操作,所以还会在堆中创建一个hello对象,s1指向堆中的hello对象,此时常量池中是没有hello对象的,但在1.6中执行intern()方法会把这个对象复制一份到常量池中,并返回常量池引用,此时s2指向的是常量池中的对象,所以在1.6版本中System.out.println(s1 == s2);会输出false
在这里插入图片描述
在JDK1.7及以上版本中,对象创建和之前一样,但由于字符串池不在永久代了,intern() 做了一些修改,s2赋值期间去常量池中找hello对象,找不到的时候不会再赋值堆中对象,会直接把引用指向堆中对象,s1和s2其实就是一个对象。所以在1.7及以上版本中System.out.println(s1 == s2);会输出true
在这里插入图片描述
四、基本类型常量池
java中基本类型的包装类的大部分都实现了常量池技术(在堆上),Byte,Short,Integer,Long,Character,Boolean六种包装类实现了,double,float两种浮点数类型的包装类没有实现。
其中Byte,Short,Integer,Long,Character这5种整型的包装类的常量池区间在-128> 127。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值