运行时常量池

运行时常量池

class文件前4个字节固定为CAFEBABE
class文件中的ConstantPool中的数据有以下类型
在这里插入图片描述

运行时常量池
运行时常量池是每个类或每个接口class文件中常量池表的运行时表示
# A run-time constant pool is a per-class or per-interface run-time representation of the constant_pool table in a class file.
它包含几种常量,从编译时已知的数字字面到必须在运行时解决的方法和字段引用
# It contains several kinds of constants, ranging from numeric literals
# known at compile-time to method and field references that must be resolved at run-time.
运行时常量池的功能类似于传统编程语言的符号表,尽管它包含的数据范围比典型的符号表要广
# The run-time constant pool serves a function similar to that of a symbol table for a conventional programming language,
# although it contains a wider range of data than a typical symbol table.
常量池(Constant Pool)就是一张表,虚拟机指令根据这张常量表找到要执行的类名,方法名,参数类型,字面量等信息
使用`javap -v Test.class`就可以看到
常量池是class文件中的,当该类被加载,常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

字符串常量池

在这里插入图片描述

public class Test {
    public static void main(String[] args) {
		// "=" 号的赋值方式并不会在堆上创建新的对象,而是在StringTable中搜索
		// 如果StringTable中有这个字符则直接引用这个字符的地址
		// 如果StringTable没有这个字符,则会在常量池中创建该字符,并引用地址
        String s1 = "a";// 程序刚开始时是没有"a"这个对象的,执行到该行代码时才会创建
        String s2 = "ab";
        String s3 = "a" + "ab";// StringTable中两个都有
        String s4 = "a" + "d";// 有一个
        String s5 = "b" + "c";// 一个都没有
    }
}
String对象中有一个不可变的值
# A String object has a constant (unchanging) value.
字符串字面量是String实例的引用
# String literals (§3.10.5) are references to instances of class String.
String类型的常量表达式总是被"内部化",以便共享唯一的实例,使用方法是String.intern
# Constant expressions of type String are always "interned" so as to share unique instances,using the method String.intern.
public native String intern();// (从string pool中找)
// A pool of strings, initially empty, is maintained privately by the class {@code String}.
// When the intern method is invoked,
// if the pool already contains a string equal to this {@code String} object as determined by 
// the {@link #equals(Object)} method, then the string from the pool is returned.
// Otherwise, this {@code String} object is added to the pool and a reference to this {@code String} object is returned.

JAVA使用jni调用C++实现的StringTable的intern方法,StringTable的intern方法跟Java中的HashMap的实现是差不多的,只是不能自动扩容.
默认大小是1009.
StringStringPool是一个固定大小的Hashtable,默认值大小长度是1009.如果放进StringPoolString非常多,就会造成Hash冲突严重.
从而导致链表会很长,链表长了后直接会造成的影响就是当调用String.intern时性能会大幅下降(因为要一个一个找).

// jdk12
String s1 = "a";
String sq = new String("a");
System.out.println(sq == s1);// false
System.out.println(sq.intern() == s1);// true

// public String(String original) {
//    this.value = original.value;
//    this.coder = original.coder;
//    this.hash = original.hash;
// }

在这里插入图片描述

// 程序中只有一个此对象
String s1 = "a";
String s2 = "a";// 并没有创建对象
String s3 = "a";// 并没有创建对象
System.out.println(s1 == s2);// true
System.out.println(s2 == s3);// true

在这里插入图片描述

public static void main(String[] args) {
	// 创建了两个String对象(可通过debug方式查看String实例的数量变化)
    String s2 = new String("a");
}
public static void main(String[] args) {
	// 只创建了一个对象(可通过debug方式查看String实例的数量变化)
    String s2 = "a";
}
public static void main(String[] args) {
    String s = "a" + "b"; // 只创建了一个对象,编译器会直接将+号优化,ConstantPool中是"ab"
}
// It is advised to use equals(), not ==, to compare two strings.
// This is because == operator compares memory locations, while equals() method compares the content stored in two objects.
public static void main(String[] args){ 
	// two objects will be created.
	// One in the Heap Area and One in the String constant pool
	// and the String object reference always points to heap area object. 
	// S1 refers to Object in the Heap Area 
	String s1 = new String("GFG"); // Line-1
	
	// S2 refers to Object in SCP Area
	String s2 = s1.intern(); // Line-2
	
	// Comparing memory locations
	// s1 is in Heap, s2 is in SCP
	System.out.println(s1 == s2); // false

	// Comparing only values
	System.out.println(s1.equals(s2)); // true

	// S3 refers to Object in the SCP Area.No need to create a new one object.
	String s3 = "GFG"; // Line-3 
	System.out.println(s2 == s3); // true
} 

在这里插入图片描述
JVM官方文档
String官方文档
intern美团
intern

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值