jvm比例,jvm简书

  jvm比例,jvm简书

  看了虚拟机(Java虚拟机的缩写)虚拟机规范,之前看类文件的描述,总是觉得很模糊,这次周末又一次看了一遍,决定写点代码分析一下,甲骨文的爪哇岛开发工具包提供了

  javap,参照这个写了简单的分析类,就是为了辅助学习用,因为规范里面都是u类型的,而且是大印第安人,使用数据输入正好符合。

  代码很简单,我也没有按照什么面向对象来分析,就是走一步算一步,写到哪算到哪,很多可能都重复了,望见谅,就是个练手。

  看代码的时候,请参照虚拟机规范看,其实这个就是个理论,关键还是虚拟机(Java虚拟机的缩写)的实现以及应用程序接口的类库,再一次感慨一下。

  注意一下,属性的分析我没写,其实也是分析字节流,实在懒的写的,以后在补上吧。整个代码就是读流,读文件内容按照预先定义的格式进行解析。

  导入Java。io。数据输入流;

  导入Java。io。io异常;

  导入Java。io。inputstream

  导入Java。文字。十进制格式;

  导入Java。文字。数字格式;

  公共类简单分类分析器{

  静态数字格式formatter=新的十进制格式(" 00 ");

  静态最终int ACC _ PUBLIC=0x0001

  静态最终int ACC _ FINAL=0x0010

  静态最终int ACC _ SUPER=0x0020

  静态最终int ACC _ INTERFACE=0x0200

  静态最终int ACC _ ABSTRACT=0x0400

  静态最终int ACC _ PRIVATE=0x0002

  静态最终int ACC _ PROTECTED=0x0004

  静态最终int ACC _ STATIC=0x0008

  静态最终int ACC _ VOLATILE=0x0040

  静态最终int ACC _ TRANSIENT=0x0080

  静态最终int ACC _ SYNCHRONIZED=0x0020

  静态最终int ACC _ NATIVE=0x0100

  静态最终int ACC _ STRICT=0x0800

  静态枚举常量PoolTag {

  CONSTANT_Class(7),CONSTANT_Fieldref(9),CONSTANT_Methodref(10),CONSTANT_InterfaceMethodref(

  11)、常量字符串(8)、常量整数(3)、常量浮点(4)、常量长整型(

  5)、常量_双精度(6)、常量_名称和Type(12)、CONSTANT_Utf8(

  1);

  私有(同Internationalorganizations)国际组织标记;

  ConstantPoolTag(int tagN) {

  this.tag=tagN

  }

  public int getTag() {

  返回标签;

  }

  公共静态ConstantPoolTag getConstantPoolTag(int tagN){

  开关(标签){

  案例7:

  返回常量_类

  案例9:

  返回常数_字段参考

  案例10:

  返回常数_方法参考

  案例11:

  return CONSTANT _ InterfaceMethodref;

  案例8:

  返回常量字符串

  案例三:

  返回常数_整数;

  案例4:

  返回常数_浮点

  案例5:

  返回常数_ Long

  案例6:

  返回常数_双精度

  案例12:

  返回CONSTANT _和Type

  案例1:

  return CONSTANT _ Utf8

  默认值:

  返回空

  }

  }

  }

  公共静态void main(String[] args) {

  InputStream fin=simpleclassanalizer。班级。getResourceAsStream( demo。类’);

  数据输入流din=新数据输入流(fin);

  印刷魔术(din);

  印刷版本(din);

  printConstantPool(din);

  printAccessFlag(din,true);

  printClassName(this ,din);

  printClassName(super ,din);

  打印接口信息(din);

  printFieldInfo(din);

  打印方法信息(德国标准);

  printClassAttributes(din);

  }

  私有静态void printClassAttributes(数据输入流din){

  尝试{

  //符合大印度人

  int attriCnt=din。readunsignedshort();

  系统。出去。println( Class Attributes: attriCnt );

  for(int I=0;我归因于;i ) {

  printAttributeInfo(din,I);

  }

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态作废打印方法信息(数据输入流din){

  尝试{

  //符合大印度人

  int方法CNT=din。readunsignedshort();

  系统。出去。println( method CNT: method CNT );

  for(int I=0;一、方法CNTi ) {

  printAccessFlag(din,false);

  int name _ index=din。readunsignedshort();

  int描述符_索引=din。readunsignedshort();

  System.out.println(方法名\ t # name _ index);

  System.out.println(方法描述符\t# 描述符_索引);

  int attributes _ count=dinreadunsignedshort();

  系统。出去。println(方法属性计数:属性_计数);

  for(int j=0;j属性_计数;j ) {

  printAttributeInfo(din,j);

  }

  }

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态void打印类名(字符串名,DataInputStream din) {

  尝试{

  //符合大印度人

  int index=din。readunsignedshort();

  系统。出去。println(名称 \ t # 索引);

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态void printFieldInfo(数据输入流din){

  尝试{

  //符合大印度人

  int字段CNT=din。readunsignedshort();

  系统。出去。println( field CNT: field CNT );

  for(int I=0;i fieldCnti ) {

  printAccessFlag(din,false);

  int name _ index=din。readunsignedshort();

  int描述符_索引=din。readunsignedshort();

  System.out.println(字段名\ t # name _ index);

  System.out.println(字段描述符\t# 描述符_索引);

  int attributes _ count=dinreadunsignedshort();

  系统。出去。println(字段属性计数:属性_计数);

  for(int j=0;j属性_计数;j ) {

  printAttributeInfo(din,j);

  }

  }

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  //未实现

  私有静态void打印属性信息(数据输入流din,int j) {

  //方法

  尝试{

  //符合大印度人

  int属性名称索引=din。readunsignedshort();

  系统。出去。println( attributename index:# attribute _ name _ index);

  //u4 - int可以替换?

  int属性长度=din。readint();

  字节[] tmp=新字节[属性长度];

  晚餐。readly(tmp);

  //系统。出去。println(属性信息:新字符串(tmp));

  //现在不分析,以后补好

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态作废打印接口信息(数据输入流din){

  尝试{

  //符合大印度人

  int接口中心=din。readunsignedshort();

  系统。出去。println(‘接口中心:‘接口中心’);

  for(int I=0;一。界面客户端;i ) {

  系统。出去。println(接口:\ t # din。readunsignedshort());

  }

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态void printAccessFlag(数据输入流din,

  布尔类接口){

  尝试{

  int访问标志=din。readunsignedshort();

  系统。出去。print( AccessFlagInfo:);

  StringBuilder buf=new StringBuilder();

  if ((accessFlag ACC_FINAL) 0) {

  buf。append(“Final”);

  }

  if (classOrInterface) {

  if ((accessFlag ACC_SUPER) 0) {

  //设置

  buf。追加( Super );

  }

  if((访问标志ACC _ INTERFACE)0){

  buf。append(“接口”);

  }否则{

  buf。append( Class );

  }

  }

  if ((accessFlag ACC_ABSTRACT) 0) {

  buf。append(“Abstract”);

  }

  //字段/方法/类必须是以下之一

  if ((accessFlag ACC_PUBLIC) 0) {

  buf。append(“Public”);

  } else if((访问标志ACC _ PRIVATE)0){

  buf。append(“Private”);

  } else if((访问标志ACC _ PROTECTED)0){

  buf。追加( Protected );

  }否则{

  buf。追加( Package );

  }

  如果(!classOrInterface) {

  //字段

  if ((accessFlag ACC_STATIC) 0) {

  buf。append(“Static”);

  }

  if ((accessFlag ACC_VOLATILE) 0) {

  buf。append( Volatile );

  }

  if((访问标志ACC _ TRANSIENT)0){

  buf。append(“瞬态”);

  }

  if((访问标志ACC _ SYNCHRONIZED)0){

  buf。追加( Synchronized );

  }

  if ((accessFlag ACC_NATIVE) 0) {

  buf。append(“本机”);

  }

  if ((accessFlag ACC_STRICT) 0) {

  buf。append( FP strict );

  }

  }

  系统。出去。println(buf。tostring().trim());

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态void printConstantPool(数据输入流din){

  尝试{

  //符合大印度人

  int poolSize=din。readunsignedshort();

  系统。出去。println( ConstantPoolSize: poolSize );

  for(int I=0;我池大小-1;i ) {

  字节标签=din。读取字节();

  readConstPool(constantpooltag。getconstantpooltag(标签),din,

  I 1);

  if((ConstantPoolTag。getconstantpooltag(tag)==ConstantPoolTag .常数_双精度)

   (ConstantPoolTag。getconstantpooltag(tag)==ConstantPoolTag .CONSTANT_Long)) {

  我;

  }

  }

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态void read const pool(ConstantPoolTag ConstantPoolTag,

  DataInputStream din,int index) {

  //只处理几种情况

  尝试{

  开关(constantPoolTag) {

  情况常量_Class:

  int name _ index=din。readunsignedshort();

  系统。出去。println( # index = constantPoolTag

  \ t名称索引:# name _ index);

  打破;

  案例常量_Utf8:

  //readUtf也读取长度

  系统。出去。println( # index = constantPoolTag \ t

  晚餐。read utf());

  打破;

  案例常数_和类型:

  名称索引=din。readunsignedshort();

  int描述符_索引=din。readunsignedshort();

  系统。出去。println( # index = constantPoolTag \ t

  # 名称索引:# 描述符索引);

  打破;

  案例常量_字符串:

  名称索引=din。readunsignedshort();

  系统。出去。println( # index = constantPoolTag \ t

  # 名称索引);

  打破;

  case CONSTANT_Methodref:

  案例常量_Fieldref:

  情况常量_InterfaceMethodref:

  名称索引=din。readunsignedshort();

  描述符索引=din。readunsignedshort();

  系统。出去。println( # index = constantPoolTag \ t

  # 名称索引:# 描述符索引);

  打破;

  情况常量_整数:

  int val=din。readint();

  系统。出去。println( # index = constantPoolTag \ t

  v= val);

  打破;

  案例常量_浮点:

  浮点fval=din。读取float();

  系统。出去。println( # index = constantPoolTag \ t

  Fv= fval);

  打破;

  情况常量_Double:

  double dval=din。read double();

  系统。出去。println( # index = constantPoolTag \ t

  dv= dval);

  打破;

  情况常量_Long:

  long lval=din。read long();

  系统。出去。println( # index = constantPoolTag \ t

  LV= lval);

  打破;

  默认值:

  返回;

  }

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态作废打印版本(数据输入流din){

  尝试{

  int版本=din。readint();

  系统。出去。打印(版本:);

  for(int I=2;我我- ) {

  系统输出打印(格式化程序。格式((版本(2-I)* 16)0x ffff));

  System.out.print(i==2?.: );

  }

  系统。出去。println();

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  私有静态void print magic(数据输入流din){

  尝试{

  int magic=din。readint();

  System.out.print(魔串:);

  for(int I=0;i i ) {

  系统输出打印(整数。toHexString((magic(3-I)* 8)0x ff));

  }

  系统。出去。println();

  } catch (IOException e) {

  e。printstacktrace();

  }

  }

  }

  写完之后,我发现谷歌上一个国人写的分析常量池的代码,当然是他整体代码的一部分,我觉得写的很好,好在结构很清晰,其实思路都是一样,所以说当思路一样的时候,人的解决方案建模能力能够看出人的水平,我还是建模和模式能力差啊。代码也附上,有兴趣的可以看看,版权不在我,望周知:

  导入Java。io。数据输入流;

  导入Java。util。ArrayList

  导入Java。util。hashmap

  publicsclassconsantpool {

  静态int count=0;

  静态intindex=1;

  staticArrayList对象l=新数组列表对象

  staticbytetag _ main

  publicstaticHashMap Integer,String consant pool=new hashmap Integer,String

  publistativoidparseconstant _ pool(int count 2,DataInputStreamin)

  抛出异常{

  计数=计数2-1;

  系统。出去。println( startparsecount= count);

  while(count - 0){

  tag _ main=in。读取字节();

  CONSTANT _ clasc=new CONSTANT _ Class();

  CONSTANT _ Utf8 _ infou=new CONSTANT _ Utf8 _ info();

  CONSTANT _ field ref _ infof=new CONSTANT _ field ref _ info();

  CONSTANT _ method ref _ infom=new CONSTANT _ method ref _ info();

  CONSTANT _ InterfaceMethodref _ info itf=new CONSTANT _ InterfaceMethodref _ info();

  CONSTANT _ String _ infos=new CONSTANT _ String _ info();

  CONSTANT _ Integer _ infoi=new CONSTANT _ Integer _ info();

  CONSTANT _ Float _ infofl=new CONSTANT _ Float _ info();

  CONSTANT _ Long _ infol=new CONSTANT _ Long _ info();

  CONSTANT _ Double _ infod=new CONSTANT _ Double _ info();

  CONSTANT _ name and type _ infon=new CONSTANT _ name and type _ info();

  c。解析(in);

  你。解析(in);

  f。解析(in);

  m。解析(in);

  itf。解析(in);

  s。解析(in);

  I .解析(in);

  fl。解析(in);

  我。解析(in);

  d。解析(in);

  不知道。解析(in);

  }

  }

  }

  interfaceconstant{

  void parse(data inputstreamin)引发异常;

  }

  类constant _ class实现常量{

  staticbytetag=0x07

  简称_索引;

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  name _ index=in。read short();

  ConsantPool.l.add(这个);

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ class name _ index=

  name _ index);

  }

  }

  }

  类constant _ Utf8 _ info实现常量{

  staticbytetag=0x01

  短长度;

  串值

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  长度=英寸。read short();

  byte[]b=新字节[长度];

  英寸改为(b);

  value=新字符串(b);

  康森特游泳池。康森特游泳池。放(康桑池。指数,数值);//添加到常量池

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ Utf8 _ info= value);

  }

  }

  }

  类constant _ String _ info实现常量{

  staticbytetag=0x08

  短字符串索引

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  string _ index=inread short();

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ String _ info String _ index=

  string _ index);

  }

  }

  }

  类constant _ field ref _ info实现常量{

  staticbytetag=0x9

  shortclass _索引

  简称和类型索引;

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  class _ index=in。read short();

  名称和类型索引=in。read short();

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ field ref _ info class _ index=

  class _ index name _ and _ type _ index=

  名称和类型索引);

  }

  }

  }

  类constant _ method ref _ info实现常量{

  staticbytetag=0x0A

  shortclass _索引

  简称和类型索引;

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  class _ index=in。read short();

  名称和类型索引=in。read short();

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ method ref _ info class _ index=

  class _ index name _ and _ type _ index=

  名称和类型索引);

  }

  }

  }

  类constant _ interface方法ref _ info实现常量{

  staticbytetag=0x0B

  shortclass _索引

  简称和类型索引;

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  class _ index=in。read short();

  名称和类型索引=in。read short();

  系统。出去。打印(consant池。索引“”);

  System.out。println( parse constant _ interface method ref _ info class _ index=

  类别索引

  名称和类型索引=

  名称和类型索引);

  }

  }

  }

  类constant _ Integer _ info实现常量{

  staticbytetag=0x03

  intbytes

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  字节=英寸。readint();

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ Integer _ info int= bytes);

  }

  }

  }

  类constant _ Float _ info实现常量{

  staticbytetag=0x04

  浮动字节;

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  字节=英寸。读取float();

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ Float _ info Float= bytes);

  }

  }

  }

  类constant _ Long _ info实现常量{

  staticbytetag=0x05

  纵向的

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  l=英寸。read long();

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ Long _ infolong= l);

  }

  }

  }

  类constant _ Double _ info实现常量{

  staticbytetag=0x06

  双值

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  值=英寸。read double();

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ Double _ info Double= value);

  }

  }

  }

  类constant _ name和type _ info实现常量{

  staticbytetag=0x0C

  简称_索引;

  短描述符_索引;

  @覆盖

  publicvoidparse(数据输入流)抛出异常{

  if(tag==ConsantPool.tag_main){

  name _ index=in。read short();

  描述符索引=in。read short();

  系统。出去。打印(consant池。索引“”);

  系统。出去。println( parse constant _ name and type _ infoname _ index=

  name _ index descriptor _ index= descriptor _ index);

  }

  }

  }

  具体大家可以google Java ConstantPool就能在第一页看见这个代码,托管在谷歌代码下面的。

  附注:修改了几个Bug,添加了对所有常量池的支持,另外我贴的别人的代码,貌似和我之前的代码犯一个毛病,就是解析长的和两倍时候,没有增加常量池索引。

  所有的8字节常量在类文件的常量池表中占据两个条目。如果常数_长信息或常数双精度信息结构是常量池表中索引n处的项,则池中的下一个可用项位于索引氮气处常量池索引n 1必须有效,但被认为是不可用的。2

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: