全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Java class文件格式之数据类型_动力节点Java学院整理

CONSTANT_Integer_info

一个常量池中的CONSTANT_Integer_info数据项, 可以看做是CONSTANT_Integer类型的一个实例。 它存储的是源文件中出现的int型数据的值。 同样, 作为常量池中的一种数据类型, 它的第一个字节也是一个tag值, 它的tag值为3, 也就是说, 当虚拟机读到一个tag值为3的数据项时, 就知道这个数据项是一个CONSTANT_Integer_info, 它存储的是int型数值的值。 紧挨着tag的下面4个字节叫做bytes, 就是int型数值的整型值。 它的内存布局如下:

下面以示例代码进行说明, 示例代码如下:

package com.bjpowernode.test; 
public class TestInt { 
 void printInt(){ 
  System.out.println(65535); 
 } 
} 

将上面的类生成的class文件反编译:

1.D:\Workspace\AndroidWorkspace\BlogTest\bin>javap -v -c -classpath . com.bjpowernode.test.TestInt  

下面列出反编译的结果, 由于反编译结果较长, 我们省略了大部分信息:

.................. 
 .................. 
Constant pool: 
 .................. 
 .................. 
 #21 = Integer   65535 
 .................. 
 .................. 
{ 
  .................. 
  .................. 
 void printInt(); 
 flags: 
 Code: 
  stack=2, locals=1, args_size=1 
   0: getstatic  #15     // Field java/lang/System.out:Ljava/io/PrintStream; 
   3: ldc   #21     // int 65535 
   5: invokevirtual #22     // Method java/io/PrintStream.println:(I)V 
   8: return 
  LineNumberTable: 
  line 6: 0 
  line 7: 8 
  LocalVariableTable: 
  Start Length Slot Name Signature 
    0  9  0 this Lcom/bjpowernode/test/TestInt; 
} 

上面的输出结果中, 保留了printInt方法的反编译结果, 并且保留了常量池中的第21项。 首先看printInt方法反编译结果中的索引为3 的字节码指令:

1.3: ldc           #21                 // int 65535  

这条ldc指令, 引用了常量池中的第21项, 而第21项是一个CONSTANT_Integer_info, 并且这个CONSTANT_Integer_info存储的整型值为65535 。 

CONSTANT_Float_info

一个常量池中的CONSTANT_Float_info数据项, 可以看做是CONSTANT_Float类型的一个实例。 它存储的是源文件中出现的float型数据的值。 同样, 作为常量池中的一种数据类型, 它的第一个字节也是一个tag值, 它的tag值为4, 也就是说, 当虚拟机读到一个tag值为4的数据项时, 就知道这个数据项是一个CONSTANT_Float_info, 并且知道它存储的是float型数值。 紧挨着tag的下面4个字节叫做bytes, 就是float型的数值。 它的内存布局如下:

举例说明, 如果源文件中的一句代码使用了一个float值, 如下所示:

void printFloat(){ 
 System.out.println(1234.5f); 
} 

那么在这个类的常量池中就会有一个CONSTANT_Float_info与之相对应, 这个CONSTANT_Float_info的形式如下:

代码反编译结果如下:

Constant pool: 
............ 
............ 
 #29 = Float    1234.5f 
........... 
........... 
{ 
............ 
............ 
 void printFloat(); 
 flags: 
 Code: 
  stack=2, locals=1, args_size=1 
   0: getstatic  #15     // Field java/lang/System.out:Ljava/io/PrintStream; 
   3: ldc   #29     // float 1234.5f 
   5: invokevirtual #30     // Method java/io/PrintStream.println:(F)V 
   8: return 
  LineNumberTable: 
  line 10: 0 
  line 11: 8 
  LocalVariableTable: 
  Start Length Slot Name Signature 
    0  9  0 this Lcom/bjpowernode/test/TestInt; 
} 

CONSTANT_Long_info

一个常量池中的CONSTANT_Long_info数据项, 可以看做是CONSTANT_Long类型的一个实例。 它存储的是源文件中出现的long型数据的值。 同样, 作为常量池中的一种数据类型, 它的第一个字节也是一个tag值, 它的tag值为5, 也就是说, 当虚拟机读到一个tag值为5的数据项时, 就知道这个数据项是一个CONSTANT_Long_info, 并且知道它存储的是long型数值。 紧挨着tag的下面8个字节叫做bytes, 就是long型的数值。 它的内存布局如下:

举例说明, 如果源文件中的一句代码使用了一个long型的数值, 如下所示:

void printLong(){ 
 System.out.println(123456L); 
} 

那么在这个类的常量池中就会有一个CONSTANT_Long_info与之相对应, 这个CONSTANT_Long_info的形式如下:

代码反编译结果为:

Constant pool: 
............. 
............. 
 #21 = Long    123456l 
............. 
............. 
{ 
.............. 
.............. 
 void printLong(); 
 flags: 
 Code: 
  stack=3, locals=1, args_size=1 
   0: getstatic  #15     // Field java/lang/System.out:Ljava/io/PrintStream; 
   3: ldc2_w  #21     // long 123456l 
   6: invokevirtual #23     // Method java/io/PrintStream.println:(J)V 
   9: return 
  LineNumberTable: 
  line 7: 0 
  line 8: 9 
  LocalVariableTable: 
  Start Length Slot Name Signature 
    0  10  0 this Lcom/bjpowernode/test/TestInt; 
} 

CONSTANT_Double_info

一个常量池中的CONSTANT_Double_info数据项, 可以看做是CONSTANT_Double类型的一个实例。 它存储的是源文件中出现的double型数据的值。 同样, 作为常量池中的一种数据类型, 它的第一个字节也是一个tag值, 它的tag值为6, 也就是说, 当虚拟机读到一个tag值为6的数据项时, 就知道这个数据项是一个CONSTANT_Double_info, 并且知道它存储的是double型数值。 紧挨着tag的下面8个字节叫做bytes, 就是double型的数值。 它的内存布局如下:


举例说明, 如果源文件中的一句代码使用了一个double型的数值, 如下所示:

void printDouble(){ 
 System.out.println(123456D); 
} 

那么在这个类的常量池中就会有一个CONSTANT_Double_info与之相对应, 这个CONSTANT_Double_info的形式如下:

代码反编译结果为:

Constant pool: 
............ 
............ 
 #21 = Double    123456.0d 
............ 
............ 
{ 
............. 
............. 
 void printDouble(); 
 flags: 
 Code: 
  stack=3, locals=1, args_size=1 
   0: getstatic  #15     // Field java/lang/System.out:Ljava/io/PrintStream; 
   3: ldc2_w  #21     // double 123456.0d 
   6: invokevirtual #23     // Method java/io/PrintStream.println:(D)V 
   9: return 
  LineNumberTable: 
  line 7: 0 
  line 8: 9 
  LocalVariableTable: 
  Start Length Slot Name Signature 
    0  10  0 this Lcom/bjpowernode/test/TestInt; 
} 

CONSTANT_String_info

在常量池中, 一个CONSTANT_String_info数据项, 是CONSTANT_String类型的一个实例。 它的作用是存储文字字符串, 可以把他看做是一个存在于class文件中的字符串对象。 同样, 它的第一个字节是tag值, 值为8 , 也就是说, 虚拟机访问一个数据项时, 判断tag值为8 , 就说明访问的数据项是一个CONSTANT_String_info 。 紧挨着tag的后两个字节是一个叫做string_index的常量池引用, 它指向一个CONSTANT_Utf8_info, 这个CONSTANT_Utf8_info存放的才是字符串的字面量。 它的内存布局如下:

 

举例说明, 如果源文件中的一句代码使用了一个字符串常量, 如下所示:

void printStrng(){ 
 System.out.println("abcdef"); 
} 

那么在这个类的常量池中就会有一个CONSTANT_String_info与之相对应, 反编译结果如下:

Constant pool: 
............ 
............ 
 #21 = String    #22   // abcdef 
 #22 = Utf8    abcdef 
............ 
............. 
{ 
............. 
............. 
 void printStrng(); 
 flags: 
 Code: 
  stack=2, locals=1, args_size=1 
   0: getstatic  #15     // Field java/lang/System.out:Ljava/io/PrintStream; 
   3: ldc   #21     // String abcdef 
   5: invokevirtual #23     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
   8: return 
  LineNumberTable: 
  line 7: 0 
  line 8: 8 
  LocalVariableTable: 
  Start Length Slot Name Signature 
    0  9  0 this Lcom/bjpowernode/test/TestInt; 
} 

其中printString方法中索引为3的字节码指令ldc引用常量池中的第21项, 第21项是一个CONSTANT_String_info, 这个位于第21项的CONSTANT_String_info又引用了常量池的第22项, 第22项是一个CONSTANT_Utf8_info, 这个CONSTANT_Utf8_info中存储的字符串是 abcdef 。 引用关系的内存布局如下:

 

总结

最后总结一下, 本文主要讲解了常量池中的五中数据项, 分别为CONSTANT_Integer_info, CONSTANT_Float_info, CONSTANT_Long_info, CONSTANT_Double_info 和CONSTANT_String_info 。 这几种常量池数据项都是直接存储的常量值,而不是符号引用。 这里又一次出现了符号引用的概念, 这个概念将会在下一篇博客中详细讲解, 因为下一篇博客要介绍的剩下的四种常量池数据项, 都是符号引用, 这四种表示符号引用的数据项又会直接或间接引用上篇文章中介绍的CONSTANT_NameAndType_info和CONSTANT_Utf8_info, 所以说CONSTANT_NameAndType_info是符号引用的一部分。

从本文中我们还可以知道。 虽然说CONSTANT_String_info是直接存储值的数据项, 但是CONSTANT_String_info有点特别, 因为它不是直接存储字符串, 而是引用了一个CONSTANT_Utf8_info, 这个被引用的CONSTANT_Utf8_info中存储了字符串。


# java  # class文件格式  # 数据类型  # Java class文件格式总结_动力节点Java学院整理  # Java class文件格式之特殊字符串_动力节点Java学院整理  # Java class文件格式之数据类型(二)_动力节点Java学院整理  # Java class文件格式之方法_动力节点Java学院整理  # Java class文件格式之属性_动力节点Java学院整理  # Java class文件格式之常量池_动力节点Java学院整理  # Java class文件格式之访问标志信息_动力节点Java学院整理  # Java class文件格式之属性详解_动力节点java学院整理  # 深入理解Java class文件格式_动力节点Java学院整理  # 是一个  # 池中  # 的是  # 值为  # 反编译  # 第一个  # 就会  # 在这个  # 一句  # 所示  # 与之  # 也就是说  # 读到  # 相对应  # 有一个  # 都是  # 举例说明  # 就知道  # 使用了  # 留了 


相关文章: ui设计制作网站有哪些,手机UI设计网址吗?  5种Android数据存储方式汇总  如何零成本快速生成个人自助网站?  建站之星如何助力网站排名飙升?揭秘高效技巧  香港服务器网站卡顿?如何解决网络延迟与负载问题?  网站app免费制作软件,能免费看各大网站视频的手机app?  如何通过FTP空间快速搭建安全高效网站?  如何快速搭建高效WAP手机网站?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?  如何快速建站并高效导出源代码?  太平洋网站制作公司,网络用语太平洋是什么意思?  小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化  建站主机功能解析:服务器选择与快速搭建指南  如何在Golang中使用replace替换模块_指定本地或远程路径  独立制作一个网站多少钱,建立网站需要花多少钱?  如何确保FTP站点访问权限与数据传输安全?  广州建站公司哪家好?十大优质服务商推荐  如何在VPS电脑上快速搭建网站?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  较简单的网站制作软件有哪些,手机版网页制作用什么软件?  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  制作公司内部网站有哪些,内网如何建网站?  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?  如何通过远程VPS快速搭建个人网站?  如何在建站主机中优化服务器配置?  如何获取免费开源的自助建站系统源码?  如何在云主机快速搭建网站站点?  如何用虚拟主机快速搭建网站?详细步骤解析  网站制作软件免费下载安装,有哪些免费下载的软件网站?  昆明高端网站制作公司,昆明公租房申请网上登录入口?  如何彻底删除建站之星生成的Banner?  公司网站的制作公司,企业网站制作基本流程有哪些?  制作国外网站的软件,国外有哪些比较优质的网站推荐?  已有域名能否直接搭建网站?  南京做网站制作公司,南京哈发网络有限公司,公司怎么样,做网页美工DIV+CSS待遇怎么样?  网站制作需要会哪些技术,建立一个网站要花费多少?  建站之星如何实现五合一智能建站与营销推广?  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  如何通过虚拟机搭建网站?详细步骤解析  官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站  如何在云服务器上快速搭建个人网站?  建站之星微信建站一键生成小程序+多端营销系统  如何在橙子建站上传落地页?操作指南详解  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  php8.4新语法match怎么用_php8.4match表达式替代switch【方法】  攀枝花网站建设,攀枝花营业执照网上怎么年审?  长沙做网站要多少钱,长沙国安网络怎么样?  建站主机服务器选购指南:轻量应用与VPS配置解析 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。