`
aswang
  • 浏览: 848223 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

ASM指南翻译-7

 
阅读更多

2.3工具

除了ClassVisitor接口,以及与之相关的三个组件ClassReader ClassAdapterClassWriterASMorg.objectweb.asm.util包中提供了一些工具用来帮助开发类生成器或者适配器,这些工具在运行时并不需要。ASM提供了一些实用类用来在运行时操作内部名称,类型描述符以及方法描述符。所有的这些工具将在下面介绍。

2.3.1类型

就像在前面章节中见到的,ASM API将编译后的class中的java类型以内部名称或者类型描述符的方式展现出来。当然,也可以将这些类型还原成源代码中定义的样子,这样就更便于阅读。但是,这需要在ClassReaderClassWriter之间进行系统转换,但是这会降低性能。这就是为什么ASM没有透明地转换内部名称和类型描述符为源代码中对等的形式。尽管如此,ASM还是提供了Type类用来在需要的时候手工地进行转换。

 

一个Type对象代表了一个java类型,它可以通过类型描述符或者Class对象来构造。这个Type类也包含了一些静态变量,用来表示基本类型,例如Type.INT_TYPEint类型的Type对象。

 

getInternalName方法返回一个Type的内部名称,例如,Type.getType(String.class).getInternalName()返回了String类的内部名称”java/lang/String”.这个方法只能用于类或者借口类型。

 

getDescriptor方法返回一个Type的描述符,例如,你可以使用Type.getType(String.class).getDescriptor()来代替”Ljava/lang/String;”。或者,使用Type.INT_TYPE.getDescriptor()来代替I

 

Type类也提供了一些静态方法用来获取一个方法的参数的Type对象和返回值的Type对象,主要是通过它的类型描述符或者java.lang.reflect.Method对象来获得。例如,Type.getArgumentTypes(“(I)V”)返回一个包含Type.INT_TYPE的数组,同样地Type.getReturnType(“(I)V”)返回一个Type.VOID_TYPE对象。

 

2.3.2 TraceClassVisitor

为了检查类的生成或者转换是否如你期望,单靠ClassWriter返回的字节数组是没有多大帮助的,因为它不可读。相比较而言,一个文本表示更易于阅读和使用,而这就是TraceClassVisitor提供的。这个类,就如它的名字暗示的一样,实现了ClassVisitor借口,并且构造解析过的类的文本表示。因此,你可以使用TraceClassVisitor来替代ClassWriter,这样你可以跟踪真正生成的是什么。更好的办法是同时使用这两者,TraceClassVisitor可以跟踪代码生成,除此之外,它也可以将所有的调用委托给另外一个visitor,如ClassWriter:

ClassWriter cw = new ClassWriter(0);

TraceClassVisitor cv = new TraceClassVisitor(cw, printWriter);

cv.visit(...);

...

cv.visitEnd();

byte b[] = cw.toByteArray();

 

上面的代码创建了一个TraceClassVisitor,然后委托所有对它的调用给cw,并且将对这些方法的调用以文本方式交给printWriter来打印。例如,在2.2.3章节中的例子使用TraceClassVisitor会输出如下内容:

// class version 49.0 (49)

// access flags 1537

public abstract interface pkg/Comparable implements pkg/Mesurable {

// access flags 25

public final static I LESS = -1

// access flags 25

public final static I EQUAL = 0

// access flags 25

public final static I GREATER = 1

// access flags 1025

public abstract compareTo(Ljava/lang/Object;)I

}

注意,为了弄清楚在转换链中到底发生了什么,你可以在生成类或者转换链过程的任何点使用TraceClassVisitor,而不仅仅是在ClassWriter之前使用。注意,通过这个类生成的类的文本表示可以通过String.equals()很容易地进行比较。

 

2.3.3 CheckClassAdapter

ClassWriter并不会检查它的方法调用是否按照合适的顺序以及参数是否有效。这样就可能生成无效的代码,而被java虚拟机的验证工具所拒绝。为了尽可能地检测出这些错误,可以使用CheckClassAdapter。和TraceClassVisitor一样,这个类也实现了ClassVisitor接口,它也会将对它的方法调用委托给其他的ClassVisitor,例如一个TraceClassVisitor或者ClassWriter。尽管如此,除了打印类的文本表示,这个类会在将方法调用委托给下一个ClassVisitor之前,检查对它的方法调用顺序是否合理,以及参数是否有效。如果发生错误,将会抛出IllegalStateException或者IllegalArgumentException

 

为了检查一个类,并且打印它的文本表示,最终创建一个字节数组,你可以参考下面的代码:

ClassWriter cw = new ClassWriter(0);

TraceClassVisitor tcv = new TraceClassVisitor(cw, printWriter);

CheckClassAdapter cv = new CheckClassAdapter(tcv);

cv.visit(...);

...

cv.visitEnd();

byte b[] = cw.toByteArray();

 

注意,如果这些ClassVisitor的顺序不同,那么它们会以不同的顺序执行。例如,下面的代码会导致在跟踪代码以后再检查类。

ClassWriter cw = new ClassWriter(0);

CheckClassAdapter cca = new CheckClassAdapter(cw);

TraceClassVisitor cv = new TraceClassVisitor(cca, printWriter);

 

就像TraceClassVisitor一样,为了检查类是否有效,你也可以在生成类或者转换类的链的任何节点使用CheckClassAdapter,而不仅仅是在ClassWriter之前。

 

2.3.4 ASMifierClassVisitor

这个类也实现了ClassVisitor接口,它的每个方法会打印出调用它的java代码。例如,调用visitEnd会打印出cv.visitEnd();,结果是,当这个visitor解析一个类时,它会打印出使用ASM来生成这个类的源代码。当你使用这个类去解析一个存在的类时,你会发现它很有用。例如,如果你不知道如何使用ASM来生成一些编译后的类,那么你可以先写出这些类的源代码,然后使用javac来编译,再然后使用ASMifierClassVisitor来解析,这样就能够得到使用ASM来生成这些类的源代码了。

 

ASMifierClassVisitor可以通过命令行直接使用,如下面的例子:

java -classpath asm.jar:asm-util.jar \

         org.objectweb.asm.util.ASMifierClassVisitor \

         java.lang.Runnable

 

生成的代码经过缩进以后,就是下面的代码:

package asm.java.lang;

import org.objectweb.asm.*;

public class RunnableDump implements Opcodes {

         public static byte[] dump() throws Exception {

                   ClassWriter cw = new ClassWriter(0);

                   FieldVisitor fv;

                   MethodVisitor mv;

                   AnnotationVisitor av0;

                   cw.visit(V1_5, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE,

                            "java/lang/Runnable", null, "java/lang/Object", null);

                   {

                            mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "run", "()V",

                                     null, null);

                            mv.visitEnd();

                   }

                   cw.visitEnd();

                   return cw.toByteArray();

         }

}

1
1
分享到:
评论

相关推荐

    ASM3.0指南翻译

    ### ASM3.0指南翻译——深入理解Java字节码引擎库 #### 1. 引言与背景 在软件开发领域,程序分析、生成及转换技术的应用极为广泛,覆盖从语法解析到语义分析,再到代码优化、混淆、调试、性能监控及面向切面编程等...

    ASM4使用指南.pdf

    根据提供的文件信息,以下是关于“ASM4使用指南.pdf”文档中所提及知识点的详细介绍: 1. ASM库介绍: ASM(Java字节码操作和分析框架)是一个Java字节码操作与分析框架。它被设计用于直接以类文件的形式读写和修改...

    ASM30-LINK30和实用程序用户指南

    根据给定的文件信息,我们可以提炼出以下几个关键的知识点,主要围绕着ASM30-LINK30和实用程序用户指南,以及Microchip Technology Inc.的相关信息进行深入解析: ### 1. 微芯科技(Microchip Technology Inc.)...

    C32Asm 反汇编工具

    在压缩包中的"读我.txt"文件,很可能是C32Asm的使用指南或注意事项,它可能包含了安装步骤、配置选项、命令行参数以及一些使用技巧。而"c32asm"可能是个可执行文件,即C32Asm工具本身,或者是一个示例文件,用于演示...

    《Win32asm与Radasm开发教程》第二阶段视频的代码和资料下载

    《汇编程序员之代码风格指南》,此书是我自己翻译的中文版,网上已有很多 地方可下载,学习汇编语言而不注意编码风格是很吃亏的事,此书能教你什么时候 该做什么,什么时候不应该做什么。良好的编码风格对于win32...

    反汇编工具 win32asm

    描述中提到的“汉化了的,好用”,意味着这个win32asm工具已经被翻译成了中文,这对于中文用户来说是一个极大的便利,因为它消除了语言障碍,使得不懂英文的开发者也能轻松使用。通常,反汇编器的界面和文档都是英文...

    ADS开发工具详细教程

    src DCD 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4 dst DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 END ``` 该程序定义了两个缓冲区`src`和`dst`,并通过循环将`src`中的...

    汇编程序员之代码风格指南

    本指南由著名的汇编语言专家Randall Hyde撰写,并由jhkdiy翻译成中文版。该指南旨在帮助程序员理解如何提高他们所编写的汇编代码的可读性。书中通过一系列实例来展示常见的问题及其解决方案,这些实例均来自互联网上...

    GCC中文手册.PDF

    本中文手册是由一位热心人士翻译整理的,其内容主要摘自GNU C编译器的官方文档。手册旨在为用户提供一个简明扼要的GCC使用指南,特别是针对编译器选项的解释。 #### 二、手册重要声明 1. **免责声明**:手册的内容...

    c++实现的mips汇编器

    - `ReadMe.txt`:通常包含项目说明、使用指南或者注意事项。 - `ConsoleApplication1`:可能是C++编译生成的可执行程序,包含了汇编和反汇编的功能。 - `汇编与反汇编exe`:这可能是最终生成的汇编和反汇编器的可...

    AsmToE汇编机器码转换工具

    - 中文伪指令.txt 可能包含了易语言中的特殊指令,这些指令在易语言中用中文表示,但被翻译为对应的汇编指令。 - 测试代码.txt 包含了一些示例代码,用于测试软件的功能和性能。 - 高级指令.txt 可能介绍了更复杂或...

    Linux 汇编语言开发指南

    ### Linux 汇编语言开发指南 #### 一、简介 汇编语言作为一种低级语言,在现代编程领域中虽然不如高级语言那样普及广泛,但它在特定场景下的优势不容忽视。尤其是在Linux环境中,汇编语言被用于优化性能敏感的模块...

    Windows 汇编语言编程指南

    全部翻译完了,给我的感觉就是这篇文章是为已有汇编基础但从未接触过Windows汇编编程的读者写的,虽然对我来说这些内容很简单,但也觉得说的很详细了,好过国内许多三言两语的所谓菜鸟教程;但如果读者想全面学习Win...

    Pro-E三维转二维的一些设置.pdf

    - `PRO/Emenu_translatyesnopro/enno-yes-both` 可能指的是菜单的翻译设置,用户可以根据需要选择中文、英文或者是双语界面。 - `menu_fontARIAL`:指定菜单使用的字体为Arial,确保了软件界面的一致性和可读性。 ...

    Oracle Database Reference 10.2.pdf

    2. **限制性使用**:根据许可证协议中的规定,用户不得擅自复制、翻译、广播、修改、授权、传输、分发、展示或表演软件的任何部分,除非许可证协议中有明确规定或许可,或者法律允许的情况。 3. **反向工程禁止**:...

    乐曲程序的设计与实现

    在提供的文件列表中,"huibian.doc"可能是关于ASM乐曲程序设计的一个指南或教程,可能详细介绍了如何编写和调试ASM代码以创建音乐程序。而"www.pudn.com.txt"可能是从一个编程讨论论坛或资源网站下载的资料,可能...

    dREAMtHEATER翻的国外汇编教程

    2. **Win32汇编编程指南**: - **Win32环境下的开发工具**:介绍用于编写、编译和调试Win32汇编程序所需的工具链。 - **创建Win32汇编应用程序**:讲解如何从零开始构建一个简单的Win32汇编程序。 - **Win32 API...

Global site tag (gtag.js) - Google Analytics