常量池介绍

news2025/1/5 21:19:35

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

最近看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.class
  Last modified 2019-9-19; size 448 bytes
  MD5 checksum 2dd9130ca78cd6781198832576a02832
  Compiled from "A.java"
public interface com.xiaoer.A
  minor version: 0
  major version: 54
  flags: 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: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #1                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #2                  // String defaultB
         5: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 5: 0
        line 6: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  this   Lcom/xiaoer/A;

  public static void staticA();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: getstatic     #1                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #4                  // String staticA
         5: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 8: 0
        line 9: 8
}

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

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/581363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux互斥锁(pthread_mutex)知识点总结

对于多线程程序来说,我们往往需要对这些多线程进行同步。同步(synchronization)是指在一定的时间内只允许某一个线程访问某个资源。而在此时间内,不允许其它的线程访问该资源。我们可以通过互斥锁(mutex)&a…

1、Vue.js---Vue核心

目录 Vue是什么 什么是渐进式: Vue 的特点 与其它 JS 框架的关联 Vue 周边库 搭建Vue开发环境(2种方式) 1、直接用 2、NPM Hello小案例 小结: 模板语法 代码 小结: 数据绑定 代码: 小结&…

11、渗透性测试及验收测试

目录 什么是安全测试 安全测试与常规测试的区别 SQL注入漏洞 SQL注入漏洞会带来以下几种常见的后果: SQL注入漏洞攻击流程 注入点类型 SQL注入的防范措施 XSS跨站脚本漏洞 XSS原理解析 XSS类型 1、反射型XSS 2、存储型XSS 3、存储型XSS 查找XSS漏洞的…

1.4. 运算符与表达式

在 Java 中,运算符是用于执行特定操作的符号,而表达式是由变量、常量和运算符组成的一段代码,用于计算值。本节将介绍 Java 中的常用运算符和表达式的使用。 1.4.1. 算术运算符 Java 支持以下算术运算符: 加法(&…

C语言基础习题讲解

C语言基础习题讲解 运算符判断简单循环 运算符 1. 设计一个程序, 输入三位数a, 分别输出个,十,百位. (0<a<1000) 样例输入: 251 样例输出: 2 5 1 #include <stdio.h> int main() {int input 0;int x 0;int y 0;int z 0;scanf("%d", &input);x …

chatgpt赋能python:Python三次方函数介绍

Python三次方函数介绍 Python是一种流行的编程语言&#xff0c;用于各种应用程序&#xff0c;包括数据分析和机器学习。Python三次方函数是Python语言中的一个内置函数&#xff0c;可用于计算一个数字的三次方。本文将介绍Python三次方函数的相关内容并提供一些示例。 Python…

chatgpt赋能python:Python三个数相加的方法与应用

Python三个数相加的方法与应用 在现代编程语言中&#xff0c;Python是一个非常流行的语言。Python语言的的特点是易学易用、功能强大、语法简洁等。在Python中&#xff0c;运算也是非常方便的&#xff0c;特别是对于数值计算。本文将讨论如何在Python中实现三个数的加法运算&a…

LeetCode高频算法刷题记录11

文章目录 1. 最大正方形【中等】1.1 题目描述1.2 解题思路1.3 代码实现 2. 在排序数组中查找元素的第一个和最后一个位置【中等】2.1 题目描述2.2 解题思路2.3 代码实现 3. 搜索二维矩阵 II【中等】3.1 题目描述3.2 解题思路3.3 代码实现 4. 翻转二叉树【简单】4.1 题目描述4.2…

POWERLINK协议在stm32单片机+w5500移植成功经验分享

连续折腾了多个晚上&#xff0c;又趁周末又花了一天时间&#xff0c;终于把powerlink协议移植成功到单片机上啦。本想放弃&#xff0c;但想了下不管我能不能用上&#xff0c;结个尾吧&#xff0c;分享给有需要的人。放弃并不难&#xff0c;但坚持一定很酷。为了移植测试这个协议…

Arcgis小技巧【13】——和数据统计相关的各种工具

在Arcgis中可以通过属性表中字段的【统计】功能或使用统计相关的工具对属性表进行数据统计。 在Arcgis工具箱中有一组【统计分析】工具集&#xff0c;不仅包含对属性数据执行标准统计分析&#xff08;例如平均值、最小值、最大值和标准差&#xff09;的工具&#xff0c;也包含…

表的增删改查

目录 表的增删改查create(创建)单行数据 全列插入多行数据 指定列插入插入否则更新替换 retrieve(读取)SELECT 列全列查询指定列查询查询字段为表达式为查询结果指定别名结果去重 WHERE 条件英语不及格的同学及英语成绩 ( < 60 )&#xff08;<&#xff09;语文成绩在 […

个人博客-SpringBoot+Vue3项目实战(6)- 二次封装Axios

目录 前言新建axiosUtil.js 文件基本配置统一URL.env文件与环境变量示例参考资料 请求头超时时间 request 拦截器response 拦截器统一Api管理测试 前言 在上文中&#xff0c;我们封装了统一的后端数据返回结果&#xff0c;有了标准化的接口数据&#xff0c;我们就可以针对它&a…

【Linux性能优化】你知道什么是平衡负载么

什么是平衡负载 首先大家思考一下&#xff0c;当你发现自己的服务变慢时&#xff0c;你会首先使用什么命令来排查&#xff1f;我通常做的第一件事&#xff0c;就是执行top或者uptime命令来了解系统的负载情况。比如像下面这样&#xff0c;我在命令行里输入top命令&#xff0c;…

Springboot +spring security,创建SpringSecurity项目

一.简介 搭建第一个Spring Security项目&#xff0c;看看如何利用Spring Security来保护Java Web项目。 二. 创建SpringSecurity项目 我们这边使用idea进行创建。 2.1创建一个基于Maven的Project项目。 2.2设置项目名称和存储位置 2.3添加项目依赖 在pom.xml文件中&#x…

LeetCode 128 最长连续序列

LeetCode 128 最长连续序列 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/longest-consecutive-sequence/description/ 博主Github&#xff1a;https://github.com/GDUT-Rp/LeetCode 题目&#xff1a; 给定一个未排…

【双系统ubuntu安装指引】配置一个顺手的深度学习环境

文章目录 前言1. 前置安装 前言 版本&#xff1a;ubuntu20.04 桌面版 normal安装 第一件事&#xff0c;切换源&#xff1a;换成阿里源 https://blog.csdn.net/u010092716/article/details/125832062 第二件事输入法安装&#xff0c;指引在这里 https://blog.csdn.net/q54434431…

JMeter性能测试:JMeter多用户并发模拟及压测结果分析

目录 JMeter设置 JMeter线程组 JMeter压测实例 View Results Tree Aggregate Report 命令行方式执行压测 jtl文件解析 JMeter多用户并发模拟 JMeter设置 多用户并发数的多少与计算机内存有关&#xff0c;设置 jmeter.bat (Windows) 或者 jmeter.sh (Linux)&#xff1a;…

chapter6:SpringBoot与Docker

1. 简介 Docker是一个开源的轻量级应用容器引擎, 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到Linux机器中实现虚拟化。(沙箱机制) Docker支持将软件编译成一个镜像&#xff1b;然后在镜像中各种软件做好配置&#xff0c;将镜像…

《数据库系统概论》期末考试手写笔记汇总+考试注意事项+反思(超全整理总结!!!)

&#xff08;一&#xff09;期末考试手写笔记汇总 笔记内容为期末考试前整理&#xff08;结合测试题PPT作业题目课本&#xff09; 很多内容为纯手写&#xff0c;非常的全乎&#xff0c;预祝你期末可以考个好成绩&#x1f339; 第二章第三章&#xff08;25分&#xff09; (…

JS 深度克隆的实现方法

方法一&#xff1a;正统做法&#xff08;扩展性高&#xff0c;推荐&#xff09; function test() { this.a 1; this.b 2; } test.prototype.c 3; // 原型上的属性 const obj new test(); console.log("原对象", obj); console.log("克隆后的对象", dee…