首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

ASM指南通译-7

2012-10-06 
ASM指南翻译-72.3工具public abstract compareTo(Ljava/lang/Object)I}注意,为了弄清楚在转换链中到底发

ASM指南翻译-7

2.3工具

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 = newTraceClassVisitor(cw, printWriter);

CheckClassAdapter cv = newCheckClassAdapter(tcv);

cv.visit(...);

...

cv.visitEnd();

byte b[] = cw.toByteArray();

?

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

ClassWriter cw = new ClassWriter(0);

CheckClassAdapter cca = newCheckClassAdapter(cw);

TraceClassVisitor cv = newTraceClassVisitor(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 implementsOpcodes {

???????? publicstatic byte[] dump() throws Exception {

?????????????????? ClassWritercw = new ClassWriter(0);

?????????????????? FieldVisitorfv;

?????????????????? MethodVisitormv;

?????????????????? AnnotationVisitorav0;

?????????????????? 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();

?????????????????? returncw.toByteArray();

???????? }

}

热点排行