文档章节

自己解析一个class文件

SunnyWu
 SunnyWu
发布于 07/10 17:43
字数 1530
阅读 17
收藏 0

我们都知道,java因为一次编译处处运行,等特性,使其目前发展的特别大,java能做到这一点,主要归功于JVM。程序员写完的程序通过编译成class字节文件,JVM负责将class文件解释给机器执行。 我们来自己写一个程序,和JVM一样,简单的完成对于class的解析。

开始之前我们先对Class有一个简单的了解

  • Class文件是一组以8位字节为基础单位的二进制流,当遇到需要8位字节以上空间的数据项时,则会按照高位在前的方式分隔成若干个8位字节进行存储。
  • Class文件由无符号数和表构成。
  • 无符号数:以u1、u2、u4、u8分别代表1个字节、2个字节、4个字节和8个字节的无符号数,可以用来描述数字、索引引用、数量值、按照UTF-8编码构成的字符串值。
  • 表:由多个无符号数或其他表作为数据项构成的复杂数据类型,所有表都习惯性地以“_info”结尾。

Class文件格式如下

类型 描述 备注
u4 magic 魔数
u2 minor_version 小版本号
u2 major_version 主版本号
u2 constant_pool_count 常量池大小,从1开始
cp_info constant_pool[constant_pool_count - 1] 常量池信息
u2 access_flags 访问标志
u2 this_class 类索引
u2 super_class 父类索引
u2 interfaces_count 接口个数
u2 interfaces[interfaces_count] 接口类索引信息
u2 fields_count 字段数
field_info fields[fields_count] 字段表信息
u2 methods_count 方法数
method_info methods[methods_count] 方法表信息
u2 attributes_count 属性个数
attribute_info attributes[attributes_count] 属性表信息

准备一个普通的类,编译成IBopClient.class,并是sublime 打开

cafe babe 0000 0033 0016 0700 1307 0014
0100 0765 7865 6375 7465 0100 5c28 4c63
6f6d 2f62 6169 7761 6e67 2f62 6f70 2f72
6571 7565 7374 2f49 426f 7052 6571 7565
7374 3b4c 6a61 7661 2f6c 616e 672f 5374
7269 6e67 3b4c 6a61 7661 2f6c 616e 672f
436c 6173 733b 294c 6a61 7661 2f6c 616e
672f 4f62 6a65 6374 3b01 000a 4578 6365
7074 696f 6e73 0700 1501 0009 5369 676e
6174 7572 6501 0068 3c54 3a4c 6a61 7661
2f6c 616e 672f 4f62 6a65 6374 3b3e 284c
636f 6d2f 6261 6977 616e 672f 626f 702f
7265 7175 6573 742f 4942 6f70 5265 7175
6573 743b 4c6a 6176 612f 6c61 6e67 2f53
7472 696e 673b 4c6a 6176 612f 6c61 6e67
2f43 6c61 7373 3c54 543b 3e3b 2954 543b
0100 4a28 4c6a 6176 612f 6c61 6e67 2f53
7472 696e 673b 4c6a 6176 612f 6c61 6e67
2f53 7472 696e 673b 4c6a 6176 612f 6c61
6e67 2f53 7472 696e 673b 294c 6a61 7661
2f6c 616e 672f 5374 7269 6e67 3b01 000b
6578 6563 7574 6541 7379 6e01 006f 284c
636f 6d2f 6261 6977 616e 672f 626f 702f
7265 7175 6573 742f 4942 6f70 5265 7175
6573 743b 4c6a 6176 612f 6c61 6e67 2f53
7472 696e 673b 4c6a 6176 612f 6c61 6e67
2f43 6c61 7373 3b4c 6a61 7661 2f6c 616e
672f 496e 7465 6765 723b 294c 6a61 7661
2f6c 616e 672f 4f62 6a65 6374 3b01 007b
3c54 3a4c 6a61 7661 2f6c 616e 672f 4f62
6a65 6374 3b3e 284c 636f 6d2f 6261 6977
616e 672f 626f 702f 7265 7175 6573 742f
4942 6f70 5265 7175 6573 743b 4c6a 6176
612f 6c61 6e67 2f53 7472 696e 673b 4c6a
6176 612f 6c61 6e67 2f43 6c61 7373 3c54
543b 3e3b 4c6a 6176 612f 6c61 6e67 2f49
6e74 6567 6572 3b29 5454 3b01 0008 7365
7450 726f 7879 0100 1628 4c6a 6176 612f
6c61 6e67 2f53 7472 696e 673b 4929 5601
0010 7365 7441 7574 686f 7269 7a61 7469
6f6e 0100 2728 4c6a 6176 612f 6c61 6e67
2f53 7472 696e 673b 4c6a 6176 612f 6c61
6e67 2f53 7472 696e 673b 2956 0100 0a53
6f75 7263 6546 696c 6501 000f 4942 6f70
436c 6965 6e74 2e6a 6176 6101 0021 636f
6d2f 6261 6977 616e 672f 626f 702f 636c
6965 6e74 2f49 426f 7043 6c69 656e 7401
0010 6a61 7661 2f6c 616e 672f 4f62 6a65
6374 0100 2363 6f6d 2f62 6169 7761 6e67
2f62 6f70 2f63 6c69 656e 742f 426f 7045
7863 6570 7469 6f6e 0601 0001 0002 0000
0000 0005 0401 0003 0004 0002 0005 0000
0004 0001 0006 0007 0000 0002 0008 0401
0003 0009 0001 0005 0000 0004 0001 0006
0401 000a 000b 0002 0005 0000 0004 0001
0006 0007 0000 0002 000c 0401 000d 000e
0000 0401 000f 0010 0000 0001 0011 0000
0002 0012 

魔数 cafe babe

minor_version 0000

major_version 0033 ,十进制是51

常量池-0016

版本号后面是常量池,常量池中常量的数量是不固定的,所以常量池的入口处有一个u2类型的数据,表示常量池中常量的数值大小。 0x0016f十进制是22,表示常量池常量数为22(注意常量池计数是从1而不是0开始),使用“javap -v BMWCar”命令可以查看Class文件的信息如下

Classfile /Users/mac/Documents/other/bw/bopsdk-openapi-1.0.2-Release/com/baiwang/bop/client/IBopClient.class
  Last modified 2019-6-24; size 916 bytes
  MD5 checksum caabed00c0d617ed9139705bb56f1f4b
  Compiled from "IBopClient.java"
public interface com.baiwang.bop.client.IBopClient
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
Constant pool:
   #1 = Class              #19            // com/baiwang/bop/client/IBopClient
   #2 = Class              #20            // java/lang/Object
   #3 = Utf8               execute
   #4 = Utf8               (Lcom/baiwang/bop/request/IBopRequest;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
   #5 = Utf8               Exceptions
   #6 = Class              #21            // com/baiwang/bop/client/BopException
   #7 = Utf8               Signature
   #8 = Utf8               <T:Ljava/lang/Object;>(Lcom/baiwang/bop/request/IBopRequest;Ljava/lang/String;Ljava/lang/Class<TT;>;)TT;
   #9 = Utf8               (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
  #10 = Utf8               executeAsyn
  #11 = Utf8               (Lcom/baiwang/bop/request/IBopRequest;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Integer;)Ljava/lang/Object;
  #12 = Utf8               <T:Ljava/lang/Object;>(Lcom/baiwang/bop/request/IBopRequest;Ljava/lang/String;Ljava/lang/Class<TT;>;Ljava/lang/Integer;)TT;
  #13 = Utf8               setProxy
  #14 = Utf8               (Ljava/lang/String;I)V
  #15 = Utf8               setAuthorization
  #16 = Utf8               (Ljava/lang/String;Ljava/lang/String;)V
  #17 = Utf8               SourceFile
  #18 = Utf8               IBopClient.java
  #19 = Utf8               com/baiwang/bop/client/IBopClient
  #20 = Utf8               java/lang/Object
  #21 = Utf8               com/baiwang/bop/client/BopException
{
  public abstract <T extends java.lang.Object> T execute(com.baiwang.bop.request.IBopRequest, java.lang.String, java.lang.Class<T>) throws com.baiwang.bop.client.BopException;
    descriptor: (Lcom/baiwang/bop/request/IBopRequest;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
    flags: ACC_PUBLIC, ACC_ABSTRACT
    Exceptions:
      throws com.baiwang.bop.client.BopException
    Signature: #8                           // <T:Ljava/lang/Object;>(Lcom/baiwang/bop/request/IBopRequest;Ljava/lang/String;Ljava/lang/Class<TT;>;)TT;

  public abstract java.lang.String execute(java.lang.String, java.lang.String, java.lang.String) throws com.baiwang.bop.client.BopException;
    descriptor: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    flags: ACC_PUBLIC, ACC_ABSTRACT
    Exceptions:
      throws com.baiwang.bop.client.BopException

  public abstract <T extends java.lang.Object> T executeAsyn(com.baiwang.bop.request.IBopRequest, java.lang.String, java.lang.Class<T>, java.lang.Integer) throws com.baiwang.bop.client.BopException;
    descriptor: (Lcom/baiwang/bop/request/IBopRequest;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Integer;)Ljava/lang/Object;
    flags: ACC_PUBLIC, ACC_ABSTRACT
    Exceptions:
      throws com.baiwang.bop.client.BopException
    Signature: #12                          // <T:Ljava/lang/Object;>(Lcom/baiwang/bop/request/IBopRequest;Ljava/lang/String;Ljava/lang/Class<TT;>;Ljava/lang/Integer;)TT;

  public abstract void setProxy(java.lang.String, int);
    descriptor: (Ljava/lang/String;I)V
    flags: ACC_PUBLIC, ACC_ABSTRACT

  public abstract void setAuthorization(java.lang.String, java.lang.String);
    descriptor: (Ljava/lang/String;Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_ABSTRACT
}
SourceFile: "IBopClient.java"

后面部分没有验证,只列索引

访问标志

类索引、父类索引

接口索引

字段表

方法表

属性表

本文转载自:http://wuxiongwei.com/archives/class

下一篇: 什么是IPAAS
SunnyWu
粉丝 12
博文 66
码字总数 11164
作品 0
苏州
架构师
私信 提问
自己动手实现一个Java Class解析器

最近在写一个私人项目,名字叫做ClassAnalyzer,ClassAnalyzer的目的是能让我们对Java Class文件的设计与结构能够有一个深入的理解。主体框架与基本功能已经完成,还有一些细节功能日后再增加...

通哥
2017/03/04
0
0
spring mvc 扫描与注解

在spring mvc中扫描注解机制是我们理解javabean是怎么被加载,是如何被spring进行管理的第一步。那spring mvc 是如何扫描所有的编译文件并对注解进行操作的呢,下面我们来看下: 在spring-mv...

www19
2017/06/07
0
0
Java类加载与初始化

来源:http://www.cnblogs.com/zhguang/p/3154584.html 类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理解java其它机制将有重要作用。 每个类编...

SimplePoint
2017/02/14
0
0
JsoupXPath v2.0-Beta 发布,HTML 解析器  

JsoupXPath v2.0-Beta 发布了,2.0 版本是一次非常彻底的重构,基于Antlr4针对html解析完全重新实现了W3C XPATH 1.0标准语法(http://www.w3.org/TR/1999/REC-xpath-19991116 ),提供更加强...

无极小子
2018/04/24
1K
2
第三天:XML&反射

一、XML 1 什么是XML XML全称为Extensible Markup Language,意思是可扩展的标记语言。XML语法上和HTML比较相似,但HTML中的元素是固定的,而XML的标签是可以由用户自定义的 2、应用常见 <1...

孤魂1996
2017/10/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

无回路有向图的拓扑排序

因公司业务需要,在表单中每个字段都会配置自动计算,但自动计算公式中会引用到其他字段中的值。所以希望可以根据计算公式,优先计算引用的公式。所以最终使用了无回路有向图的扩扑排序来实现...

兜兜毛毛
54分钟前
5
0
如何抢占云栖大会C位?史上最强强强攻略来了

点击观看视频: APSARA云栖大会开发者情怀 原文链接 本文为云栖社区原创内容,未经允许不得转载。

阿里云官方博客
今天
6
0
Kubernetes 从懵圈到熟练:集群服务的三个要点和一种实现

作者 | 声东 阿里云售后技术专家<br /> 文章来源:Docker,点击查看原文。 <br />以我的经验来讲,理解 Kubernetes 集群服务的概念,是比较不容易的一件事情。尤其是当我们基于似是而非的理解...

阿里巴巴云原生
今天
9
0
PHP7.3的新特性

2018年12月6日,PHP7.3正式版发布,在PHP7.2基础上进行了大量错误修复和安全优化,性能提升10%! 从目前的更新说明来看,PHP 7.3 并不是一个主打新特性的版本,包含更多的是 bug 修复。PHP 7...

迅睿CMS-PHP开源CMS程序
今天
8
0
Tomcat 应用中并行流带来的类加载问题

本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/f-X3n9cvDyU5f5NYH6mhxQ 作者:肖铭轩、王道环 随着 Java8 的不断流行,越来越多的开发人员使用并行流(parallel)...

vivo互联网技术
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部