常量池介绍

news/2025/2/7 7:01:32/

 什么是“字面量”和“符号引用”和"直接引用"

最近看jvm时遇到了“字面量”和“符号引用”这两个概念,它们被存放在运行时常量池,看了一些博客以后对这两个概念有了初步认识。

字面量可以理解为实际值,int a = 8中的8和String a = "hello"中的hello都是字面量

符号引用就是一个字符串,只要我们在代码中引用了一个非字面量的东西,不管它是变量还是常量,它都只是由一个字符串定义的符号,这个字符串存在Class文件常量池里,类加载的时候第一次加载到这个符号时,就会将这个符号引用(字符串)解析成直接引用(指针)

符号引用主要包括三种常量:
    1.类和接口的全限定名
    2.字段的名称和描述符
    3.方法的名称和描述符

 直接引用可以是:
      1.直接指向目标的指针。(个人理解为:指向对象,类变量和类方法的指针)
      2.相对偏移量。      (指向实例的变量,方法的指针)
      3.一个间接定位到对象的句柄。

 

 java的变量有哪些

 什么是常量

定义一个变量,用final去修饰,这个变量被赋值一次就不可被改变了, 就成了常量

分为三种:

1).静态常量: final修静态变量

2).实例常量: final修实例变量

3).局部常量: final修局部变量

常量池存什么

1).常量池包含字符串常量池,存的是字符串常量.

2).常量池包含五种基本类型的包装类.即Byte,Short,Integer,Long,Character,Boolean, 

这5种包装类默认创建了数值[-128,127]的相应类型的缓存数据,但是超出此范围仍然会去创建新的对象。

而两种浮点数类型的包装类Float,Double并没有实现常量池技术

3).被final修饰的变量, 它们是静态常量\实例常量\局部常量

什么是常量池?

0.什么是常量池

常量池的本质是缓存。不同的类共用一个运行时常量池
常量池分为:

  1. Class 文件常量池(非运行时常量池,本地文件)
  2. 运行时常量池(方法区内存中,元空间)
  3. 字符串常量池(堆内存)

1.Class 文件常量池(非运行时常量池,本地文件)

Class常量池中存放的编译期生成的各种字面量和符号引用。这部分内容将在类加载后进入方法区的运行时常量池中存放。
接口A源码

package com.xiaoer;public interface A {default void defaultB() {System.out.println("defaultB");}static void staticA() {System.out.println("staticA");}
}

 执行javap -verbose ByteCode.class查看class文件结构。

Classfile /E:/work_space/04 study/test01/target/classes/com/xiaoer/A.classLast modified 2019-9-19; size 448 bytesMD5 checksum 2dd9130ca78cd6781198832576a02832Compiled from "A.java"
public interface com.xiaoer.Aminor version: 0major version: 54flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
Constant pool:#1 = Fieldref           #17.#18        // java/lang/System.out:Ljava/io/PrintStream;#2 = String             #7             // defaultB#3 = Methodref          #19.#20        // java/io/PrintStream.println:(Ljava/lang/String;)V#4 = String             #14            // staticA#5 = Class              #21            // com/xiaoer/A#6 = Class              #22            // java/lang/Object#7 = Utf8               defaultB#8 = Utf8               ()V#9 = Utf8               Code#10 = Utf8               LineNumberTable#11 = Utf8               LocalVariableTable#12 = Utf8               this#13 = Utf8               Lcom/xiaoer/A;#14 = Utf8               staticA#15 = Utf8               SourceFile#16 = Utf8               A.java#17 = Class              #23            // java/lang/System#18 = NameAndType        #24:#25        // out:Ljava/io/PrintStream;#19 = Class              #26            // java/io/PrintStream#20 = NameAndType        #27:#28        // println:(Ljava/lang/String;)V#21 = Utf8               com/xiaoer/A#22 = Utf8               java/lang/Object#23 = Utf8               java/lang/System#24 = Utf8               out#25 = Utf8               Ljava/io/PrintStream;#26 = Utf8               java/io/PrintStream#27 = Utf8               println#28 = Utf8               (Ljava/lang/String;)V
{public void defaultB();descriptor: ()Vflags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: getstatic     #1                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #2                  // String defaultB5: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnLineNumberTable:line 5: 0line 6: 8LocalVariableTable:Start  Length  Slot  Name   Signature0       9     0  this   Lcom/xiaoer/A;public static void staticA();descriptor: ()Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=0, args_size=00: getstatic     #1                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #4                  // String staticA5: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnLineNumberTable:line 8: 0line 9: 8
}

2.运行时常量池(方法区内存中,元空间)

在jvm在执行某个类的时候,必须经过加载、链接(验证、准备、解析)、初始化,

在加载阶段:将class文件常量池加载到运行时常量池的过程,这里需要强调一下不同的类共用一个运行时常量池,同时在进入运行时常量池的过程中,多个class文件中常量池中相同的字符串只会存在一份在运行时常量池,这也是一种优化。

运行时常量池相对于class常量池一大特征就是具有动态性,java规范并不要求常量只能在运行时才产生,也就是说运行时常量池的内容并不全部来自class常量池,在运行时可以通过代码生成常量并将其放入运行时常量池中,这种特性被用的最多的就是String.intern()。

3.字符串常量池(堆内存)


http://www.ppmy.cn/news/100424.html

相关文章

vue基于Python的图书商城销售系统qo85w

系统以浏览器/服务器模式即B/S模板式为基础。本系统使用MySQL数据库,利用Python开发的操作系统;主要的功能有个人中心、用户管理、图书资讯管理、图书类型管理、图书信息管理、爬虫管理、留言板管理、系统管理、订单管理等组成。 本文首先介绍了现代化图书销售系统管…

组队系统(一)

游戏进入区服,旋转罗盘,以罗盘方向限定登陆地点,进出游戏罗盘指向不同,遇到的玩家不同,产生游戏社团成员在线的差别。语言聊天,语音转文字,为记录锁定记录。好友群系统,在线玩家&…

贪吃蛇游戏的制作记录

关于蛇的实现代码 #include "snake.h" #include "globalvar.h" #include <graphics.h> int fangXiang 1;//方向 0 右 1 上 2 左 3 下 int snakeHang[100] { 10,11,12,13,14 };//蛇 每节所在行 int snakeLie[100] { 10,10,10,10,10 };//蛇 每节所…

剑指 Offer 11. 旋转数组的最小数字解题思路

文章目录 题目解题思路优化 题目 把一个数组最开始的若干个元素搬到数组的末尾&#xff0c;我们称之为数组的旋转。 给你一个可能存在 重复 元素值的数组 numbers &#xff0c;它原来是一个升序排列的数组&#xff0c;并按上述情形进行了一次旋转。请返回旋转数组的最小元素。…

Dream音频芯片开发概论

1 项目需求 2 开发平台介绍 Dream S.A.S France公司网站&#xff1a;https://www.dream.fr Dream全系列的芯片包含SAM2000 series ICs、SAM3000 series ICs以及SAM5000 series ICs。 SAM5000 series ICs包括 sam5504、sam5704、sam5708、sam5808、sam5716、sam5916。 目前drea…

【牛客算法BM2】 链表内指定区间反转

​ 你好&#xff0c;欢迎来到我的博客&#xff01;作为一名程序员&#xff0c;我经常刷LeetCode题目来提升自己的编程能力。在我的博客里&#xff0c;我会分享一些我自己做过的题目和解题思路&#xff0c;希望能够帮助到大家。今天&#xff0c;我想和大家分享一道挑战性较高的题…

Django学习笔记002之resetfull应用

学习目标&#xff1a; 学习resetfull接口 掌握Django web基础设施 学习内容&#xff1a; 1.学习resetfull接口 简介 人工智能解释&#xff1a; 应用场景 以下是人工智能使用Django框架实现的restfull接口代码&#xff1a; #views.py from django.http import JsonRespon…

机器学习常识 6: kNN

摘要: 具有讽刺意味的是: 机器学习最基本的算法居然是不学习, 也称为惰性学习 (lazy learning). k k kNN (k nearest neighbors) 通过计算样本间的距离 (相似度) 来确定待预测样本应与哪些训练样本的标签保持一致. 1. 基本思想 为了应对一场考试, 我们可以不学习, 而在考场上…