javassist示例

javassist的作用是动态生成字节码。

package com.zhang;
class Fighter {}

public class Assist_Test {
    public static void main_modify(String[] args) throws NotFoundException, 
                    CannotCompileException, IOException {
        //修改已有类,添加name字段。前提是该类没有被加载
        ClassPool pool = ClassPool.getDefault();
        //CtClass (compile-time class)
        CtClass cc = pool.get("com.zhang.Fighter");
        cc.addField(new CtField(pool.get("java.lang.String"), "name", cc));
        //生成class文件
        //translates the CtClass object into a class file and writes it on a local disk
        cc.writeFile();
    }
    
    public static void main(String[] args) throws CannotCompileException, NotFoundException, InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {  
        // 创建类  
        ClassPool pool = ClassPool.getDefault();  
        CtClass cls = pool.makeClass("com.zhang.Player");  
        
        // 添加私有成员name及其getter、setter方法  
        CtField nameField = new CtField(pool.get("java.lang.String"), "name", cls);  
        nameField.setModifiers(Modifier.PRIVATE);  
        cls.addField(nameField, Initializer.constant(""));  
        cls.addMethod(CtNewMethod.setter("setName", nameField));  
        cls.addMethod(CtNewMethod.getter("getName", nameField));  
          
        // 添加无参的构造体  
        CtConstructor cons = new CtConstructor(new CtClass[] {}, cls);  
        cons.setBody("{name = "default";}");  
        cls.addConstructor(cons);  
          
        // 添加有参的构造体  
        cons = new CtConstructor(new CtClass[] {pool.get("java.lang.String")}, cls);  
        cons.setBody("{$0.name = $1;}");  
        cls.addConstructor(cons);  
          
        // 打印创建类的类名
        Class playerClass = cls.toClass();
        System.out.println(playerClass);
          
        // 通过反射创建无参的实例,并调用getName方法  
        Object obj = Class.forName("com.zhang.Player").newInstance();  
        Method getter = obj.getClass().getMethod("getName");  
        System.out.println(getter.invoke(obj));  
          
        // 调用其setName方法  
        Method setter = obj.getClass().getMethod("setName", new Class[] {String.class});  
        setter.invoke(obj, "zhang");  
        System.out.println(getter.invoke(obj));  
          
        // 通过反射创建有参的实例,并调用getName方法  
        obj = Class.forName("com.zhang.Player").getConstructor(String.class).newInstance("nobody");  
        getter = obj.getClass().getMethod("getName");  
        System.out.println(getter.invoke(obj));  
    }  
  
}

dubbo中的JavassistCompiler和JavassistProxyFactory使用了javassist包生成class文件。

原文地址:https://www.cnblogs.com/allenwas3/p/8340760.html