java动态生成类javassist

news2024/12/23 14:27:10

 简述

    Javassist(Java Programming Assistant)是一个 操作Java 字节码的类库,主要用于在运行时或编译时修改 Java 类的字节码

它提供了相对简单的 API,让开发者可以动态地创建、修改和加载 Java 类 , 从而实现诸如动态代理、AOP(面向切面编程)、代码生成等高级功能。

API学习

1)ClassPool

作用:ClassPool 作为一个类管理器,用于动态加载、操作 (对类的字段、方法进行增删改查操作) 和生成 Java 类的字节码。        

相关API

ClassPool.getDefault()

介绍:获取默认类池,采用单例模式,每次获取的类池都是同一个

makeClass(String className)、

    makeInterface(String className)、

    makeAnnotation(String className)

介绍:在内存中创建类、接口、注解的字节码,返回的都是CtClass对象,此时还并未将类装载到JVM

get(String className) 、

    getCtClass(String className)

介绍:获取内存中类的字节码对象

2)CtClass

作用:封装类的字节码信息(这里的类是统称,代表Java中的类、接口、注解等)

相关API

void addField(CtField f)、

   void addMethod(CtMethod m)、

   void addConstructor(CtConstructor c)

添加字段、方法、构造器

void addInterface(CtClass ctInterface)、

    void setInterfaces(CtClass[] list)

继承一个接口、多个接口

③ void setSuperclass(CtClass clazz)

指定父类

④ Class<?> toClass()

将字节码类装载到JVM,并返回Class对象

⑤ void writeFile(String directoryName)

将类保存到文件

应用

导入maven依赖

<!--  javassist  -->
<dependency>
   <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.29.2-GA</version>
</dependency>
<!--  单元测试  -->
<dependency>
   <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

创建如下的一个接口,一个类

package com.xxx;
​
public interface FunctionInterface {
    void print(Object o);
}
package com.xxx;
​
public class FunctionImpl implements FunctionInterface{
    public void print(Object o) {
        System.out.println(o);
    }
}

利用javassist生成类代码如下:

① 在内存中创建接口FunctionInterface的字节码,并加载到JVM

 Class<?> makeFunctionInterface() throws Exception {
     //  1.获取默认类池
     ClassPool classPool = ClassPool.getDefault();
     //  2.创建接口的内存字节码
     CtClass functionInterfaceCt = classPool.makeInterface("com.xxx.FunctionInterface");
     //  3.在内存中添加方法声明
     //      3.1创建方法声明,并指定所属
     CtMethod printMethodDeclare = CtMethod.make("void print(Object o);", functionInterfaceCt);
     //      3.2添加方法声明
     functionInterfaceCt.addMethod(printMethodDeclare);
     //  4.将接口装载到虚拟机
     Class<?> functionInterface = functionInterfaceCt.toClass();
     return functionInterface;
 }

② 在内存中创建类FunctionImpl的字节码,并加载到JVM

Class<?> makeFunctionImpl() throws Exception {
     //  1.获取默认类池
    ClassPool classPool = ClassPool.getDefault();
    //  2.创建类的内存字节码
    CtClass functionImplCt = classPool.makeClass("com.xxx.FunctionImpl");
    //  3.继承接口
    functionImplCt.addInterface(classPool.getCtClass("com.xxx.FunctionInterface"));
    //  4.在内存中添加方法实现
    //      4.1创建方法实现,并指定所属
    CtMethod printMethodImpl = CtMethod.make("public void print(Object o){System.out.println(o);}", functionImplCt);
    //      4.2添加方法实现
    functionImplCt.addMethod(printMethodImpl);
    //  5.将类装载到虚拟机
    Class<?> functionImpl = functionImplCt.toClass();
    return functionImpl;
}

③ 通过反射测试对象的生成以及print方法的调用

void testNewObject() throws Exception {
     //  1.反射创建对象
    Object functionImplObject = Class.forName("com.xxx.FunctionImpl").newInstance();
    //  2.获取print方法
    Method printMethod = functionImplObject.getClass().getMethod("print", Object.class);
    //  3.执行方法
    printMethod.invoke(functionImplObject, "hello, javassist!");
}

问题解决

java.lang.reflect.InaccessibleObjectException:如果JDK版本>8,那么添加如下JVM参数和环境变量参数:

JVM参数:--add-opens java.base/java.lang=ALL-UNNAMED

环境变量:--add-opens java.base/sun.net.util=ALL-UNNAMED

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2197444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用友Yonbuilder 平台使用教程序

用友Yonbuilder 平台使用教程 目录概述需求&#xff1a; 设计思路实现思路分析 免费下载参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for change,c…

opencv学习:利用帧差法实现对视频移动物体的识别、帧差法的优缺点及完整代码实现

基本概念 帧差法是视频处理和计算机视觉领域中用于移动检测的一种简单而有效的方法。它主要依赖于连续视频帧之间的像素差异来识别场景中的移动对象。 帧差法&#xff1a; 定义&#xff1a;帧差法通过比较连续的视频帧之间的差异来检测移动对象。基本思想是移动对象会在连续的…

基于unbantu操作系统下的docker安装全教程

目录 检查docker安装环境 1.检查服务器的CPU和操作系统版本是否为docker支持的版本。 2.卸载已有的docker 安装docker 1.创建目录 2.下载GPG秘钥 3.添加Docker的APT源 4.更新APT包索引并安装Docker 5.运行docker并配置镜像加速器 安装docker-compose 使用apt命令下载…

MAC中滚轮方向和Windows相反的解决方案

MACOS外接鼠标滚轮方向与Windows相反 MAC中滚轮方向和Windows相反&#xff0c;很难受 在使用MACOS操作系统时&#xff0c;滚轮的方向和Windows系统中的相反&#xff0c;这一点常常让人感到不适应和困惑。当第一次切换到MAC电脑时&#xff0c;许多用户会发现他们的习惯滚动操作…

LORD-GX5-45 ROS安装

1、驱动安装 https://github.com/LORD-MicroStrain/MSCL 上述下载 x64:C&#xff0c;在下载完的deb文件下执行 sudo dpkg -i <PACKAGE_NAME>.deb #install MSCL sudo apt install -f #install dependencies2、源码安装 #新建工作空间 mkdir -p ~…

Windows系统编程(三)线程并发

进程与线程 进程&#xff1a;直观的说就是任务管理器中各种正在运行的程序。对于操作系统来说&#xff0c;进程仅仅是一个数据结构&#xff0c;并不会真实的执行代码 线程&#xff1a;通常被称作但并不真的是轻量级进程或实际工作中的进程&#xff0c;它会真实的执行代码。每…

环形链表(c语言)

1.//环形链表 //输入&#xff1a;head [3,2,0,-4], pos 1 //输出&#xff1a;true //解释&#xff1a;链表中有一个环&#xff0c;其尾部连接到第二个节点。 //输入&#xff1a;head [1, 2], pos 0 //输出&#xff1a;true //解释&#xff1a;链表中有一个环&#xff0c;其…

保留字作为数据表字段导致的问题!!!

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;乡下小哥编程。回复 Java全套视频教程 或 前端全套视频教…

考拉悠然携手中国系统打造城市智能中枢,让城市更聪明更智慧

在21世纪的科技浪潮中&#xff0c;智慧城市建设已成为推动城市现代化进程的重要引擎。随着人工智能技术的飞速发展&#xff0c;AI正以前所未有的速度融入智慧城市管理的每一个角落&#xff0c;从交通出行到公共安全&#xff0c;从环境保护到城市管理&#xff0c;无一不彰显着智…

SCRM呼叫中心高保真Axure原型 源文件分享

在数字化时代&#xff0c;客户关系管理&#xff08;CRM&#xff09;对于企业的成功至关重要。SCRM呼叫中心后台作为一款专为CRM设计的软件原型&#xff0c;致力于为企业提供高效、智能的客户沟通解决方案。本文将详细介绍该产品的核心功能及其对企业提升客户满意度和销售业绩的…

《Linux从小白到高手》理论篇:Linux的进程管理详解

本篇将介绍Linux的进程管理相关知识&#xff0c;并将深入介绍Linux的进程间相互通信。 进程就是运行中的程序&#xff0c;一个运行着的程序&#xff0c;可能有多个进程。 比如Oracle DB&#xff0c;启动Oracle实例服务后&#xff0c;就会有多个进程。 Linux进程分类 在 Linux…

如何下载和安装CLion,图文详解

一、下载 登录JetBrains官网&#xff0c;下载最新版本的Clion&#xff0c;Clion目前没有社区版&#xff0c;都是专业版。 二、安装 1、启动Clion安装程序&#xff0c;下一步。 2、修改安装目录&#xff0c;下一步。 3、创建桌面快捷方式&#xff0c;更新PATH变量&#xff0…

Transforms(一)

一、概念 transforms就像是一个工具箱&#xff0c;里面装有很多类 &#xff08;比如&#xff1a;totensor、resize等&#xff0c;可以在结构里查看到一个列表&#xff09;&#xff0c;类就是工具。 但是类不能直接使用&#xff0c;要创建其实例对象之后才能调用&#xff08;to…

国庆假期互联网产品故障事件(神州租车、国航、公邮)盘点

一晃七天假期已经过去了&#xff0c;节后第一天大家股市都赚了盆满钵满吧&#xff0c;盘点一下国庆期间互联网产品故障吧。 一、神州租车&#xff1a; 10 月 2 日&#xff0c;有网友反馈神州租车今日出现服务问题&#xff0c;“App 小程序都崩了”。 对此&#xff0c;神州租车…

【自然语言处理】(2) --Word2Vec实现

文章目录 Word2Vec实现一、训练模型1. 数据预处理2. 构建训练数据3. 搭建word2vec网络&#xff08;CBOW&#xff09;4. 装配设备5. 构建训练模型6. 优化器7. 损失函数8. 迭代模型 二、测试模型1. 预测单词2. 生成词嵌入词典3. 保存训练后的词向量 总结 Word2Vec实现 Word2Vec …

『网络游戏』业务系统基类【08】

创建脚本&#xff1a;SystemRoot.cs 编写脚本&#xff1a;SystemRoot.cs 修改脚本&#xff1a;LoginSys.cs 修改脚本&#xff1a;WindowRoot.cs 运行项目 - 效果相同 本章结束

付费计量系统实体和接口(5)

13.7.2 Sub-classification of the Accounting functions 收费功能的子分级 The Accounting function maintains a current balance of all credit and charge transactions performed in the payment meter. These activities together constitute the Meter Accounting Proce…

小蒋聊技术——DevOps 是什么“玩意”?

时间&#xff1a;2024年 10月 08日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 音频&#xff1a;喜马拉雅 大家好&#xff0c;欢迎来到“小蒋聊技术”&#xff0c;我是小蒋&#xff01;今天我们来聊聊一个时下特别火的概念—…

渐开线起始圆和基圆之间有约束关系吗?

最近看到了一个问题&#xff1a;“渐开线起始圆和基圆之间有约束关系吗&#xff1f;有起始圆要比基圆大某个固定数值这么一说吗&#xff1f;”&#xff0c;这期咱们就来说说这个话题&#xff1a; 如上图所示&#xff1a;一对圆柱齿轮副中&#xff0c;一个齿轮的渐开线起始圆是…

什么是数据编织

What Is Data Fabric? 【dataCamp】 What Is Data Fabric? Data fabric is a unified data architecture that connects disparate data sources, simplifying access and management while ensuring consistency and security across the entire data landscape. Data Fa…