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
包来支持。
CtMethod
和CtConstructor
提供了insertBefore()
,insertAfter()
和addCatch()
方法。他们都是在已存在的方法体中插入代码段,用户可以使用Java中的源代码文本方式编写代码段。Javassist包含一个简单的Java编译器用于处理源文本,接收Java中的源文本并编译成字节码到方法体中。
插入代码段在指定行也是可以的(如果行号表在class文件中的话),CtMethod
的insertAt()
方法和CtConstructor
在源class文件中获取源文本和行号,它将编译源文本并且在指定行插入编译过的代码。