java运行时常量池位置_java虚拟机运行时常量池

java虚拟机运行时常量池

时间:20180228

运行时常量池是方法区的一部分。Class文件(也就是.java文件编译后生成的字节码.class文件)中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用()。这部分内容将在类加载后进入方法区的运行时常量池中存放。

常量池主要用于存放两大类常量:字面量(Literal)和符号引用量(Symbolic References),字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:

类和接口的全限定名

字段名称和描述符

方法名称和描述符

一般来说除了保存class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。

运行时常量池与Class文件常量池的区别

运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性。运行期间也能将新的常量放入池中,比如String类的intern()方法。

举例:

package com.test5;

public class Test {

public static void main(String[] args) {

String s1 = "abc";

String s2 = "abc";

System.out.println(s1 == s2);

String s3 = new String("abc");

String s4 = new String("abc");

System.out.println(s1 == s2);

//基本数据类型和抽象数据类型都会放在局部变量表中(虚拟机栈的栈帧中)

//String 是抽象数据类型,抽象数据类型存放的是引用,

System.out.println("s1 == s2? :" + (s1 == s2));

//System.out.println("s1 == s2?" + s1 == s2);返回结果为 false为什么?

System.out.println("s1 == s3? :" + (s1 == s3));

System.out.println("s1 == s3? :" + (s1 == s3.intern()));

System.out.println("s3 == s4? :" + (s3 == s4));

}

}

结果:

true

true

s1 == s2? :true

s1 == s3? :false

s1 == s3? :true

s3 == s4? :false

图解分析

a380f727ff86?utm_campaign

图解分析

文字分析

String s1 = "abc";

String是抽象数据类型,而抽象数据类的引用(抽象数据类型变量)s1存放在局部变量表中。(此处时s1本身也就是局部变量,理应存放在局部变量表中???)。"abc"为字符串,字符串的创建都存放在运行时常量池。字符串为字面量(Literal),常量池主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)。

String s2 = "abc";

s2的分析同上。只是需要注意的是在常量池中存储的数据都是不重复的。此时s1和s2都指向常量池中同一块区域。因此s1==s2返回true;

String s3 = new String("abc");

而new创建的是对象实例,存储在堆中。s3指向堆中某一块区域,因此s1!=s3;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值