Skip to content

Latest commit

 

History

History
51 lines (33 loc) · 3.42 KB

4-自省和定制.md

File metadata and controls

51 lines (33 loc) · 3.42 KB

自省和定制

CtClass提供了自省的一些方法。Javassist的内省功能和Java反射API的内省功能兼容。 CtClass提供了getName()getSuperclass()getMethods()等等方法。CtClass也提供了修改类定义的方法,允许添加一个新的成员变量、构造器、方法,也可以检测方法体。 方法由CtMethod对象表示。CtMethod提供了修改方法定义的几个方法。注意:如果一个方法继承了某个类,则CtMethod表示为是在父类中声明的方法。一个CtMethod对象对应一个方法声明。

例如,如果类Point声明了一个方法move(),而Point类的的一个子类ColorPoint没有覆盖move()方法,这两个move()方法即Point中声名的和ColorPoint中继承的都由相同的CtMethod对象表示。如果修改这个CtMethod对象标表示的方法的定义,则修改会表现到这两个方法上。如果你仅仅想修改ColorPoint中的该方法,你首先必须给ColorPoint添加一个表示move()方法的CtMethod的副本,可以通过CtNewMethod.copy()方法获得。


Javassist不允许移除一个方法或者成员变量,但是允许变更方法名。所以如果一个方法不再需要了,应该重命名并且修改为私有的:调用CtMethod中的setName()setModifiers()方法。

Javassist不允许在一个已存在的方法中添加额外的参数,为了处理这样的变更,接受额外参数或者其他参数的新方法应该添加在同一个类中。例如,如果你想在一个方法中添加一个额外的参数:

        void move(int newX, int newY){ x = newX; y = newY; }

你应该添加以下方法:

        void move(int newX, int newY, int newZ){
            // TODO 使用newZ做一些事
            move(newX, newY);
        }

Javassist 也提供了更低层次的API可以直接编辑原生class文件。例如,CtClass的getClassFile()返回一个ClassFile对象表示一个原生class文件。 CtMethod中的getMethodInfo()方法返回一个MethodInfo对象表示在class文件中的一个method_info结构。 低层次的API使用了来自JVM规范的词汇。用户必须了解class文件和字节码。更多的细节,可以参考javassist.bytecode包

如果需要被修改的类包含以下以$开头的特殊标识符,则在运行时需要javassist.runtime包来支持。

在方法体的前部、后部插入原文本

CtMethodCtConstructor提供了insertBefore(),insertAfter()addCatch()方法。他们都是在已存在的方法体中插入代码段,用户可以使用Java中的源代码文本方式编写代码段。Javassist包含一个简单的Java编译器用于处理源文本,接收Java中的源文本并编译成字节码到方法体中。

插入代码段在指定行也是可以的(如果行号表在class文件中的话),CtMethodinsertAt()方法和CtConstructor在源class文件中获取源文本和行号,它将编译源文本并且在指定行插入编译过的代码。