电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

詳解JAVA 常量池

瀏覽:3日期:2022-08-29 11:14:56

前言

對常量池的理解之前,需要熟悉的是一些術語:

字面量

在計算機科學中,字面量(literal)是用于表達源代碼中一個固定值的表示法(notation)。幾乎所有計算機編程語言都具有對基本值的字面量表示,諸如:整數、浮點數以及字符串;而有很多也對布爾類型和字符類型的值也支持字面量表示;還有一些甚至對枚舉類型的元素以及像數組、記錄和對象等復合類型的值也支持字面量表示法。C語言關于復合字面量的介紹可參考: [1] 。

百度也給了一個例子:

這個object-c 的例子,容易理解。

#include <stdio.h>int main(void){ int a = 10; // 10為int類型字面量 char a[] = {'Hello world!'} // Hello world 為字符串形式字面量 ............. // 以此類推,不再贅述 return 0;}

正文

JVM常量池主要分為Class文件常量池、運行時常量池,全局字符串常量池,以及基本類型包裝類對象常量池。

我在網上找了一個例子:

private int value = 1;public String s = 'abc';public final static int f = 0x101;public static void main(String[] args){}public void setValue(int v){final int temp = 3;this.value = temp + v;}public int getValue(){return value;}

編譯后:

下面只截取了一部分,常量池:

public class test.program minor version: 0 major version: 57 flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #1 // test/program super_class: #3 // java/lang/Object interfaces: 0, fields: 3, methods: 4, attributes: 1Constant pool: #1 = Class #2 // test/program #2 = Utf8 test/program #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 value #6 = Utf8 I #7 = Utf8 s #8 = Utf8 Ljava/lang/String; #9 = Utf8 f #10 = Utf8 ConstantValue #11 = Integer 257 #12 = Utf8 <init> #13 = Utf8 ()V #14 = Utf8 Code #15 = Methodref #3.#16 // java/lang/Object.'<init>':()V #16 = NameAndType #12:#13 // '<init>':()V #17 = Fieldref #1.#18 // test/program.value:I #18 = NameAndType #5:#6 // value:I #19 = String #20 // abc #20 = Utf8 abc #21 = Fieldref #1.#22 // test/program.s:Ljava/lang/String; #22 = NameAndType #7:#8 // s:Ljava/lang/String; #23 = Utf8 LineNumberTable #24 = Utf8 LocalVariableTable #25 = Utf8 this #26 = Utf8 Ltest/program; #27 = Utf8 main #28 = Utf8 ([Ljava/lang/String;)V #29 = Utf8 args #30 = Utf8 [Ljava/lang/String; #31 = Utf8 setValue #32 = Utf8 (I)V #33 = Utf8 v #34 = Utf8 temp #35 = Utf8 getValue #36 = Utf8 ()I #37 = Utf8 SourceFile #38 = Utf8 program.java

好的下面介紹class 常量池;

class 常量池

主要包括:字面量和符號引用

首先字面量不是全部的字面量,如果不明白什么是字面值請看上面;

字符字面值:

#7 = Utf8 s#20 = Utf8 abc

用final修飾的成員變量

#9 = Utf8 f#11 = Integer 257

大概包含的就是這兩種。

符號引用

符號引用主要設涉及編譯原理方面的概念,包括下面三類常量:

類和接口的全限定名,也就是java/lang/String;這樣,將類名中原來的'.'替換為'/'得到的,主要用于在運行時解析得到類的直接引用,像上面

#5 = Class #33 // JavaBasicKnowledge/JavaBean#33 = Utf8 JavaBasicKnowledge/JavaBean

字段的名稱和描述符,字段也就是類或者接口中聲明的變量,包括類級別變量和實例級的變量

#4 = Fieldref #5.#32 // JavaBasicKnowledge/JavaBean.value:I#5 = Class #33 // JavaBasicKnowledge/JavaBean#32 = NameAndType #7:#8 // value:I

#7 = Utf8 value#8 = Utf8 I

//這兩個是局部變量,值保留字段名稱#23 = Utf8 v#24 = Utf8 temp

可以看到,對于方法中的局部變量名,class文件的常量池僅僅保存字段名。

方法中的名稱和描述符,也即參數類型+返回值

#21 = Utf8 setValue #22 = Utf8 (I)V

#25 = Utf8 getValue #26 = Utf8 ()I

其實并不需要怎么關注符號引用。

那么這些class 常量池有什么好處呢?

運行時常量池是方法區的一部分,所以也是全局貢獻的,我們知道,jvm在執行某個類的時候,必須經過加載、鏈接(驗證、準備、解析)、初始化,在第一步加載的時候需要完成:

通過一個類的全限定名來獲取此類的二進制字節流

將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構

在內存中生成一個類對象,代表加載的這個類,這個對象是java.lang.Class,它作為方法區這個類的各種數據訪問的入口。

類對象和普通對象是不同的,類對象是在類加載的時候完成的,是jvm創建的并且是單例的,作為這個類和外界交互的入口, 而普通的對象一般是在調用new之后創建。

上面的第二條,將class字節流代表的靜態存儲結構轉化為方法區的運行時數據結構,其中就包含了class文件常量池進入運行時常量池的過程,這里需要強調一下不同的類共用一個運行時常量池,同時在進入運行時常量池的過程中,多個class文件中常量池相同的字符串,多個class文件中常量池中相同的字符串只會存在一份在運行時常量池,這也是一種優化。

運行時常量池的作用是存儲java class文件常量池中的符號信息,運行時常量池中保存著一些class文件中描述的符號引用,同時在類的解析階段還會將這些符號引用翻譯出直接引用(直接指向實例對象的指針,內存地址),翻譯出來的直接引用也是存儲在運行時常量池中。

運行時常量池相對于class常量池一大特征就是具有動態性,java規范并不要求常量只能在運行時才產生,也就是說運行時常量池的內容并不全部來自class常量池,在運行時可以通過代碼生成常量并將其放入運行時常量池中,這種特性被用的最多的就是String.intern()。

那么就看下String.intern() 來理解:運行時常量池。

首先看下:

string x='x' 和 String x=new String('x');

有什么區別?

可以肯定的是他們的值是一樣的。

但是他們運行差別很大。string x='x' 會查找常量池,如果沒有x的話,那么會存入常量池,如果有的話,那么會存在于常量池并進行引用。

而 String x=new String('x') 則只會生成在堆中,而不會和常量池產生聯系。

注:

常量字符串和變量拼接時(如:String str3=baseStr + “01”;)會調用stringBuilder.append()在堆上創建新的對象。

那么String.intern() 是什么意思呢?這個是會去查找變量詞中有沒有,如果有的話那么會返回引用,如果沒有的話,這個和版本有關。

詳解JAVA 常量池

題目

public static void main(String[] args) {// write your code hereInteger i01=59;int i02=59;Integer i03=Integer.valueOf(59);Integer i04= new Integer(59);}public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}

問題如下:

i01 是否和 i02 相等?

i03 是否和 i01 相等。

i04 是否和 i01相等。

總結

寫的比較倉促,后續會完善好。

以上就是詳解JAVA 常量池的詳細內容,更多關于java 常量池的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 土壤墒情监测站_土壤墒情监测仪_土壤墒情监测系统_管式土壤墒情站-山东风途物联网 | 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库 | 周口风机|周风风机|河南省周口通用风机厂 | ★塑料拖链__工程拖链__电缆拖链__钢制拖链 - 【上海闵彬】 | 陕西华春网络科技股份有限公司 | sus630/303cu不锈钢棒,440C/430F/17-4ph不锈钢研磨棒-江苏德镍金属科技有限公司 | 发光字|标识设计|标牌制作|精神堡垒 - 江苏苏通广告有限公司 | 奇酷教育-Python培训|UI培训|WEB大前端培训|Unity3D培训|HTML5培训|人工智能培训|JAVA开发的教育品牌 | 二次元影像仪|二次元测量仪|拉力机|全自动影像测量仪厂家_苏州牧象仪器 | 成都软件开发_OA|ERP|CRM|管理系统定制开发_成都码邻蜀科技 | 无锡网站建设_小程序制作_网站设计公司_无锡网络公司_网站制作 | 服务器之家 - 专注于服务器技术及软件下载分享 | 东莞工作服_东莞工作服定制_工衣订做_东莞厂服 | 活性氧化铝|无烟煤滤料|活性氧化铝厂家|锰砂滤料厂家-河南新泰净水材料有限公司 | 油液红外光谱仪-油液监测系统-燃油嗅探仪-上海冉超光电科技有限公司 | 武汉不干胶印刷_标签设计印刷_不干胶标签印刷厂 - 武汉不干胶标签印刷厂家 | 兰州UPS电源,兰州山特UPS-兰州万胜商贸 | 粉丝机械,粉丝烘干机,粉丝生产线-招远市远东粉丝机械有限公司 | 防弹玻璃厂家_防爆炸玻璃_电磁屏蔽玻璃-四川大硅特玻科技有限公司 | 磁力反应釜,高压釜,实验室反应釜,高温高压反应釜-威海自控反应釜有限公司 | 电动高尔夫球车|电动观光车|电动巡逻车|电动越野车厂家-绿友机械集团股份有限公司 | 定制异形重型钢格栅板/钢格板_定做踏步板/排水沟盖板_钢格栅板批发厂家-河北圣墨金属制品有限公司 | 大倾角皮带机-皮带输送机-螺旋输送机-矿用皮带输送机价格厂家-河南坤威机械 | 线粒体膜电位荧光探针-细胞膜-标记二抗-上海复申生物科技有限公司 | 精密模具制造,注塑加工,吹塑和吹瓶加工,EPS泡沫包装生产 - 济南兴田塑胶有限公司 | 信阳网站建设专家-信阳时代网联-【信阳网站建设百度推广优质服务提供商】信阳网站建设|信阳网络公司|信阳网络营销推广 | 污水提升器,污水提升泵,地下室排水,增压泵,雨水泵,智能供排水控制器-上海智流泵业有限公司 | 飞歌臭氧发生器厂家_水处理臭氧发生器_十大臭氧消毒机品牌 | 首页 - 张店继勇软件开发工作室| 众能联合-提供高空车_升降机_吊车_挖机等一站工程设备租赁 | 炭黑吸油计_测试仪,单颗粒子硬度仪_ASTM标准炭黑自销-上海贺纳斯仪器仪表有限公司(HITEC中国办事处) | LED投光灯-工矿灯-led路灯头-工业灯具 - 山东普瑞斯照明科技有限公司 | 香港新时代国际美容美发化妆美甲培训学校-26年培训经验,值得信赖! | 储能预警-储能消防系统-电池舱自动灭火装置-四川千页科技股份有限公司官网 | 一氧化氮泄露报警器,二甲苯浓度超标报警器-郑州汇瑞埔电子技术有限公司 | 水性绝缘漆_凡立水_绝缘漆树脂_环保绝缘漆-深圳维特利环保材料有限公司 | 磁力反应釜,高压釜,实验室反应釜,高温高压反应釜-威海自控反应釜有限公司 | 2025福建平潭岛旅游攻略|蓝眼泪,景点,住宿攻略-趣平潭网 | 中药二氧化硫测定仪,食品二氧化硫测定仪|俊腾百科 | 加热制冷恒温循环器-加热制冷循环油浴-杭州庚雨仪器有限公司 | 猪I型/II型胶原-五克隆合剂-细胞冻存培养基-北京博蕾德科技发展有限公司 |