zoukankan      html  css  js  c++  java
  • 06_javassist

    【简述】

    Javassist是一个开源的java字节码操作工具,主要是对已经编译好class文件进行修改和处理,可以直接检查、修改、创建 java类。

    【javassist实例】

    package com.javassist;
    
    import javassist.*;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    
    /**
     * Created by cuixinjie on 2018/9/7.
     */
    public class JavassistTest {
    
        public static void main(String[] args) throws Exception {
            //ClassPool:ctClass对象的容器
            ClassPool pool = ClassPool.getDefault();
            //通过ClassPool深沉给一个public的新类 User.java
            CtClass ctClass = pool.makeClass("com.javassist.User");
    
            //添加属性,首先添加age属性:private Integer age;
            CtField ageField = new CtField(pool.getCtClass("java.lang.Integer"), "age", ctClass);
            ageField.setModifiers(Modifier.PRIVATE);
            ctClass.addField(ageField);
    
            //添加属性,其次添加phone属性:private String phone;
            CtField phoneField = new CtField(pool.getCtClass("java.lang.String"), "phone", ctClass);
            phoneField.setModifiers(Modifier.PRIVATE);
            ctClass.addField(phoneField);
    
            //为age和phone添加getXxx/setXxx方法
            ctClass.addMethod(CtNewMethod.getter("getAge", ageField));
            ctClass.addMethod(CtNewMethod.setter("setAge", ageField));
            ctClass.addMethod(CtNewMethod.getter("getPhone", phoneField));
            ctClass.addMethod(CtNewMethod.setter("setPhone", phoneField));
    
            //添加构造方法
            CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);
            //为构造方法添加方法体
            StringBuffer buffer1 = new StringBuffer();
            //注意:this.age = ($w)18这里加上$w,因为age是Integer类型,是一个包装类,$w代表一个包装类型
            buffer1.append("{
    this.age = ($w)18;
    this.phone = "15966668888";
    }");
            ctConstructor.setBody(buffer1.toString());
            //把构造方法添加到新的类ctClass中
            ctClass.addConstructor(ctConstructor);
    
            //添加自定义方法
            CtMethod ctMethod = new CtMethod(CtClass.voidType, "printInfo", new CtClass[]{}, ctClass);
            //为自定义的方法设置方法体
            StringBuffer buffer2 = new StringBuffer();
            buffer2.append("{
    System.out.println("I can get Alibaba's offer!");
    ");
            buffer2.append("System.out.println("my age is "+age);
    ");
            buffer2.append("System.out.println("my phone is "+phone);
    ");
            buffer2.append("}");
            ctMethod.setBody(buffer2.toString());
            ctClass.addMethod(ctMethod);
    
            //生成一个Class对象
            Class<?> clazz = ctClass.toClass();
            Object instance = clazz.newInstance();
            //反射 执行方法
            Method method = instance.getClass().getMethod("printInfo", new Class[]{});
            method.invoke(instance,null);
    
            // 把生成的class文件写入文件
            byte[] byteArr = ctClass.toBytecode();
            FileOutputStream fos = new FileOutputStream(new File("./User.class"));
            fos.write(byteArr);
            fos.close();
        }
    }

    【运行结果】

  • 相关阅读:
    Java基础学习总结(33)——Java8 十大新特性详解
    Java基础学习总结(33)——Java8 十大新特性详解
    RabbitMQ学习总结(6)——消息的路由分发机制详解
    RabbitMQ学习总结(6)——消息的路由分发机制详解
    Stanford公开课《编译原理》学习笔记(1~4课)
    补习系列(21)-SpringBoot初始化之7招式
    使用modelarts部署bert命名实体识别模型
    全面认识 RUST -- 掌控未来的雷电
    补习系列(20)-大话 WebSocket 与 "尬聊"的实现
    【开发者portal在线开发插件系列二】多条上下行消息(messageId的使用)
  • 原文地址:https://www.cnblogs.com/HigginCui/p/9613516.html
Copyright © 2011-2022 走看看