带大家进入常量池一探究竟

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

  1. 类和接口的全限定名;

  2. 字段名称和描述符;

  3. 方法名称和描述符

大部分字节码指令在执行的时候,都会进行常量池的访问。

在桢数据区,就保留着访问常量池的指针,方便去访问常量池,这个指向运行时常量池的引用就是动态链接。

动态链接==指向运行时常量池的引用(动态链接里面就是保存指向运行时常量池的引用)

字节码信息中,除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池。常量池主要用于存放两大类常量:字面量(Literal)和符号引用量(SymbolicReferences),字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:

  1. 类和接口的全限定名;

  2. 字段名称和描述符;

  3. 方法名称和描述符

运行时常量池是方法区的一部分。字节码文件中常量池内容将在类加载后进入方法区的运行时常量池中存放。

在Java源文件被编译到字节码文件中时,所有的变量和方法引用都作 为符号引用( Symbolic Reference)保存在class文件的常量池里。比如:描述一个方法调用了另外的其他方法时,就是通过常量池中指向 方法的符号引用来表示的,那么动态链接的作用就是为了将这些符号引 用转换为调用方法的直接引用。

每一个栈帧内部都包含常量池的指针(指向运行时常量池的引用),这个指针指向运行时常量池中该栈帧所属方法, 包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)

字节码文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池。这个常量池在程序运行起来以后,会将字节码信息中的常量池的内容,存放入方法区中的运行时常量池。动态链接的作用就是为了将这些符号引 用转换为调用方法的直接引用。

class文件的@头4个字节称为魔数@,它的唯一作用就是确定这个文件时候是一个能被虚拟机接受的class文件。很多图片格式都用一个魔数来标识文件类型,比如png和jpg等。在java的class文件中,这个数是0xcafebabe。接下来就是class文件的版本号,第5、6个字节是@次版本号@,第7、8个字节是@主版本号@。在这里,次版本号是0,主版本号是52,(十六进制是34),紧接着主版本号的就是@常量池@,常量池可以理解为class文件的资源仓库,它是class文件结构中与其它项目关联最多的数据类型,也是占用class文件空间最大的数据项目之一,也是class文件中第一个出现的表类型数据项目。这些符号引用在虚拟机中如果不经过转换则无法与实际内存相连接,即无法被虚拟机直接使用,在虚拟机运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析并翻译到具体的内存地址中。每项常量都是一个表,而由于各个常量的类型不一,大小也不相同,所以同样需要一个u1类型的数据来标记常量的类型,以确定其后的常量表的格式。

常量池(constant_pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量和符号引用。

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

  1. 类和接口的全限定名;

  2. 字段名称和描述符;

  3. 方法名称和描述符

常量池(constant_pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量和符号引用。

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

  1. 类和接口的全限定名;

  2. 字段名称和描述符;

  3. 方法名称和描述符

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

会把类加载过程中使用到的信息,都会用符号(#数字格式)声明出来,然后具体的你在执行某个方法的时候,你想用谁,就通过下面的方式指明:

想用谁就去动态链接运行时常量池

所有类中使用到的信息,都会用的形式

  1. 每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用。包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接 (Dynamic Linking) 。比如: invokedynamic指 令

  2. 在Java源文件被编译到字节码文件中时,所有的变量和方法引用都作 为符号引用( Symbolic Reference)保存在class文件的常量池里。比如:描述一个方法调用了另外的其他方法时,就是通过常量池中指向 方法的符号引用来表示的,那么动态链接的作用就是为了将这些符号引 用转换为调用方法的直接引用。

猜你喜欢

转载自blog.csdn.net/bjmsb/article/details/107774111