ASMSupport教程2:如何查看生成的class文件和查看log文件内容

在http://my.oschina.net/wensiqun/blog/116067中我们主要介绍了如何生成一个Helloworld的Class.

在上篇blog的基础上我们来看下接下来两个问题:
  1. 如何查看生成Class文件
  2. 如何查看log文件内容

1.查看生成的Class文件

我们是通过ClassCreator来创建Class的。而他是继承自jw.asmsupport.creator.IClassContext的。我们通过调用IClassContext的setClassOutPutPath设置其生成的class的输出路径。比如:creator.setClassOutPutPath(".//target//");

接下来我们就可以在当前文件夹下的target文件夹下找到我们生成的class。接下来我们用反编译器打开就可以看到结果。当然我们可能看到的结果格式上是会有错误的, 这是因为class文件里面保存的是堆栈操作的指令,所以只要class文件内的堆栈操作指令是合法的。这个class文件就是可以执行的,但未必反编译就正确,这些说的可能有点抽象。  

打个比方:比如我要从上海去北京,我可以选择坐飞机,也可以坐高铁,但是公司只报销乘坐飞机的路费。现在就有两种方案可以选择坐飞机或者高铁。 
 
这里就可以打个比喻来,我们的目的是从上海到北京,我们就可以将它比作class类。这个class类中有坐飞机或者做高铁的指令。最终我们是要拿到公司给报销的,这里的公司就相当于反编译器。具体如下:
  • 上海到北京----class 
  • 坐飞机or坐高铁----指令 
  • 公司----反编译器   
1.如果你坐飞机去的北京就相当于class文件是通过java源代码编译的。这种class即能达到目的(去北京)又能反编译(给公司报销)  
2.如果你是坐高铁,那这个class就只能达到目的不能报销了  
以上描述如有不清楚就掠过吧 绞尽脑汁想出的例子

2.如何查看log文件内容

asmsupport采用log4j作为日志工具,配置直接采用log4j的配置。当配置了debug级别的时候会有如下log。

DEBUG [main] create method: ------------main([Ljava/lang/String;)                 //这里表示开始创建main(String[])方法
  DEBUG [main] call method by variable :out                                                  //这里表示调用了out变量的方法
  DEBUG [main] put variable reference to stack                                              //既然要调用out变量的方法就需要将out变量的引用压入栈
  DEBUG [main] get field out from class java.lang.System and push to stack!    //通过这句话就能明白原来是调用我们最常见的System.out
  DEBUG [main] Instruction : GETSTATIC                                                      //表执行JVM指令GETSTATIC(因为out是static类型的所以这里调用GETSTATIC指令获取out)
  DEBUG [main] Stack states                                                                        //接下来这个图表表示的是栈的模型,上面GETSTATIC执行的结果就是返回一个静态field并且压入栈
  *********************************
  |         |Type                 |
  *********************************
  | ____    |Ljava/io/PrintStream;|
  |/ ___|   |                     |
  |\___ \   |                     |
  | ___) |  |                     |
  ||____/   |                     |
  *********************************
  .....
  DEBUG [main] store to local variable
  DEBUG [main] local variables states                //下面这个图表是本地变量的模型,通过图已经看出已经存放了两个本地变量,那他们分别表示什么呢
  ************************************************
  |         |Type                 |Name |Fragment|
  ************************************************
  | _       |[Ljava/lang/String;  |args |false   |   //[Ljava/lang/String;类型不就是上面方法的参数类型吗。没错,这里存放的就是我们方法的参数。
  || |      |Ljava/io/PrintStream;|myOut|false   |   //这里存放的就是上面栈中的out,是如何存的呢,继续往下看
  || |      |                     |     |        |
  || |___   |                     |     |        |
  ||_____|  |                     |     |        |
  |         |                     |     |        |
  ************************************************

  DEBUG [main] Instruction : ASTORE                  //找到了,就是这个指令ASTORE。它就是负责把栈顶元素弹出在然后存到本地变量的。
  DEBUG [main] Stack states                              //往下看 发现栈里面没东西了吧,让ASTORE给拿到local variables里去了
  ****************
  |            |Type         |
  ****************
  | ____    |                |
  |/ ___|   |                |
  |\___ \   |                |
  | ___) |  |                |
  ||____/   |               |
  ****************
  .....

  DEBUG [main] Method : main([Ljava/lang/String;) Maxs(stack:1 locals:2) //这里值分配给栈和本地变量的最大值,通过上面的图就能看到栈和本地变量的最大值是多少了。

当然,这些log是需要你对jvm字节码有一定了解的才能看明白。这个给个网址可以参照:https://www.vmth.ucdavis.edu/incoming/Jasmin/jvmref.html

上文中"如何查看log"这部分内容可能格式看得比较不清楚可以下载如下内容直接用文本工具查看:https://amssupport.googlecode.com/files/READ-LOG.txt

ASMSupport源码地址:https://amssupport.googlecode.com/svn/trunk/

ASMSupport实例地址:http://amssupport.googlecode.com/svn/trunk/asmsupport/src/test/java/example/

以上代码均可通过svn下载

最新asmsupport下载地址:https://amssupport.googlecode.com/files/asmsupport-0.2-alpha-2013-03-25.jar

原文地址:http://my.oschina.net/wensiqun/blog/117382

转载于:https://my.oschina.net/wensiqun/blog/117382

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值