字节码编程javassist之生成带有注解的类

写在前面

本文看下如何使用javassist生成带有注解的类。

1:程序

  • 测试类
package com.dahuyou.javassist.huohuo.cc;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 保留到哪个阶段,SOURCE 仅仅在源代码中保留,编译器不保留该信息。CLASS(默认保留方式),编译器保留,但VM不保留。RUNTIME VM保留,即一直在
// SOURCE作用:给人看,有点类似于注释了,但是是源代码的一部分,比如Override,告诉我们这是重写父类的方法
// CLASS作用:编译器用?咋用???
// RUNTIME作用:程序运行使用,用的最多,比如Deprecated
@Retention(RetentionPolicy.RUNTIME)
// 用在哪里 TYPE 类上 METHOD方法上 FIELD用在字段上
@Target(ElementType.TYPE)
public @interface MyAnnotationOnClazz {boolean opened() default false;String desc() default "";int number();
}
package com.dahuyou.javassist.huohuo.cc;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 保留到哪个阶段,SOURCE 仅仅在源代码中保留,编译器不保留该信息。CLASS(默认保留方式),编译器保留,但VM不保留。RUNTIME VM保留,即一直在
// SOURCE作用:给人看,有点类似于注释了,但是是源代码的一部分,比如Override,告诉我们这是重写父类的方法
// CLASS作用:编译器用?咋用???
// RUNTIME作用:程序运行使用,用的最多,比如Deprecated
@Retention(RetentionPolicy.RUNTIME)
// 用在哪里 TYPE 类上 METHOD方法上 FIELD用在字段上
@Target(ElementType.METHOD)
public @interface MyAnnotationOnMethod {String typeName() default "";long payAmount();
}
  • 生成代码类
package com.dahuyou.javassist.huohuo.cc;import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.Bytecode;
import javassist.bytecode.ConstPool;
import javassist.bytecode.MethodInfo;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.BooleanMemberValue;
import javassist.bytecode.annotation.LongMemberValue;
import javassist.bytecode.annotation.StringMemberValue;public class MyDoItttt extends ClassLoader {public static void main(String[] args) throws Exception {ClassPool pool = ClassPool.getDefault();// 创建类CtClass ctClass = pool.makeClass("com.dahuyou.javassist.huohuo.bb.Helloworld_javassist");// 创建方法
//        CtMethod queryAmount = new CtMethod(CtClass.doubleType, "queryAmount", new CtClass[]{pool.get(String.class.getName())}, ctClass);CtMethod queryAmount = new CtMethod(CtClass.doubleType, "queryAmount", new CtClass[]{}, ctClass);
//        queryAmount.addLocalVariable();
//        queryAmount.
//        CtMethod queryAmount = new CtMethod(CtClass.voidType, "queryAmount", new CtClass[]{pool.get(String.class.getName())}, ctClass);queryAmount.setModifiers(Modifier.PUBLIC);// 执行到这里,空方法public double queryAmount(String var1) {}就有了ctClass.addMethod(queryAmount);MethodInfo methodInfo = queryAmount.getMethodInfo();// 获取常量池,注意虽然是通过类信息对象获取的,但常量池是属于类级别的,只不过这里和方法做了关联ConstPool constPool = methodInfo.getConstPool();// 设置类注解AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.invisibleTag);Annotation clazzAnnotation = new Annotation("com/dahuyou/javassist/huohuo/cc/MyAnnotationOnClazz", constPool);// 设置类注解的属性们/*String clazzDesc() default "";String alias() default "";long timeOut() default 350;boolean opened() default false;String desc() default "";int number();*/clazzAnnotation.addMemberValue("opened", new BooleanMemberValue(true, constPool));clazzAnnotation.addMemberValue("desc", new StringMemberValue("api描述啊", constPool));
//        clazzAnnotation.addMemberValue("number", new IntegerMemberValue(455, constPool));annotationsAttribute.setAnnotation(clazzAnnotation);ctClass.getClassFile().addAttribute(annotationsAttribute); // 画龙点睛,调用类的addAttribute添加注解,没有可不行// 添加方法注解AnnotationsAttribute methodAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);Annotation methodAnnotation = new Annotation("com/dahuyou/javassist/huohuo/cc/MyAnnotationOnMethod", constPool);methodAnnotation.addMemberValue("typeName", new StringMemberValue("查询费用111", constPool));methodAnnotation.addMemberValue("payAmount", new LongMemberValue(562L, constPool));methodAttribute.setAnnotation(methodAnnotation);methodInfo.addAttribute(methodAttribute);Bytecode bytecode = new Bytecode(constPool);bytecode.addGetstatic("java/math/BigDecimal", "TEN", "Ljava/math/BigDecimal;");bytecode.addInvokevirtual("java/math/BigDecimal", "doublevalue", "()D");bytecode.addReturn(CtClass.doubleType);methodInfo.setCodeAttribute(bytecode.toCodeAttribute());ctClass.writeFile();// 以下代码总是报:Ljava/math/BigDecimal;java.lang.ClassFormatError: Arguments can't fit into locals... 感觉是本地变量表不够大导致。但不知道该如何设置System.out.println("-------华丽的分割线-------");/* byte[] bytes = ctClass.toBytecode();Class<?> clazzNew = new MyDoItttt().defineClass("com.dahuyou.javassist.huohuo.bb.Helloworld_javassist", bytes, 0, bytes.length);MyAnnotationOnClazz annotationOnClazz = clazzNew.getAnnotation(MyAnnotationOnClazz.class);System.out.println("annotationOnClazz.opened: " + annotationOnClazz.opened());System.out.println("annotationOnClazz.desc: " + annotationOnClazz.desc());MyAnnotationOnMethod annotationOnMethod = clazzNew.getDeclaredMethod("queryAmount").getAnnotation(MyAnnotationOnMethod.class);System.out.println("annotationOnMethod.payAmount: " + annotationOnMethod.payAmount());System.out.println("annotationOnMethod.typeName: " + annotationOnMethod.typeName());*/}
}

运行后查看生成的字节码:
在这里插入图片描述

写在后面

参考文章列表

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神经网络设计过程

1.可根据Iris特征直接判断 2.神经网络方法&#xff0c;采集大量的Iris特征&#xff0c;分类对应标签&#xff0c;构成数据集。 将数据集喂入搭好的神经网络结构&#xff0c;网络通过反向传播优化参数得到模型。 有新的网络送入到模型里&#xff0c;模型会给出识别结果。 3.…

低空经济火爆:无人机培训机构工作开展详解

随着低空经济的迅速崛起&#xff0c;无人机技术在多个领域得到了广泛应用&#xff0c;从航拍摄影、农业植保到物流配送、环境监测等&#xff0c;都显示出了巨大的市场潜力。无人机培训机构作为培养专业无人机驾驶和操作人才的摇篮&#xff0c;在低空经济的发展中扮演着至关重要…

Vue项目openlayers中使用jsts处理wkt和geojson的交集-(geojson来源zpi解析)

Vue项目openlayers中使用jsts处理wkt和geojson的交集-(geojson来源zpi解析) 读取压缩包中的shape看上一篇笔记&#xff1a;Vue项目读取zip中的ShapeFile文件&#xff0c;并解析为GeoJson openlayers使用jsts官方示例&#xff1a;https://openlayers.org/en/latest/examples/j…

已解决 javax.xml.transform.TransformerFactoryConfigurationError 异常的正确解决方法,亲测有效!!!

已解决 javax.xml.transform.TransformerFactoryConfigurationError 异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 一、问题分析 二、报错原因 三、解决思路 四、解决方法 五、总结 博主v&#xff1a;XiaoMing_Java 博主v&#x…

昇思25天学习打卡营第16天|Vision Transformer图像分类

昇思25天学习打卡营第16天|Vision Transformer图像分类 前言Vision Transformer图像分类Vision Transformer&#xff08;ViT&#xff09;简介模型结构模型特点 环境准备与数据读取模型解析Transformer基本原理Attention模块 Transformer EncoderViT模型的输入整体构建ViT 模型训…

【自学网络安全】:安全策略与用户认证综合实验

实验拓扑图&#xff1a; 实验任务&#xff1a; 1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3、办公区设备10.0.2.10不允许访问Dmz区…

代理详解之静态代理、动态代理、SpringAOP实现

1、代理介绍 代理是指一个对象A通过持有另一个对象B&#xff0c;可以具有B同样的行为的模式。为了对外开放协议&#xff0c;B往往实现了一个接口&#xff0c;A也会去实现接口。但是B是“真正”实现类&#xff0c;A则比较“虚”&#xff0c;他借用了B的方法去实现接口的方法。A…

未羽研发测试管理平台

突然有一些觉悟&#xff0c;程序猿不能只会吭哧吭哧的低头做事&#xff0c;应该学会怎么去展示自己&#xff0c;怎么去宣传自己&#xff0c;怎么把自己想做的事表述清楚。 于是&#xff0c;这两天一直在整理自己的作品&#xff0c;也为接下来的找工作多做点准备。接下来…

wordpress外贸建站公司案例英文模板

Indirect Trade WP外贸网站模板 WordPress Indirect Trade外贸网站模板&#xff0c;建外贸独立站用wordpress模板&#xff0c;快速搭建十分便捷。 衣物清洁wordpress独立站模板 洗衣粉、洗衣液、衣物柔顺剂、干洗剂、衣领净、洗衣皂等衣物清洁wordpress独立站模板。 家具wordpr…

Apache部署与配置

概述 介绍 Apache HTTP Server(简称Apache)是Apache的一个开源的网页服务器&#xff0c;它源自NCSAhttpd服务器&#xff0c;并经过多次修改和发展&#xff0c;如今已经成为全球范围内广泛使用的Web服务器软件之一 特点 跨平台&#xff1a;可以运行在几乎所有广泛使用的计算机平…

哪个充电宝口碑比较好?怎么选充电宝?2024年口碑优秀充电宝推荐

在如今快节奏的生活中&#xff0c;充电宝已然成为我们日常生活中的必备品。然而&#xff0c;市场上充电宝品牌众多&#xff0c;质量参差不齐&#xff0c;如何选择一款安全、可靠且口碑优秀的充电宝成为了消费者关注的焦点。安全性能不仅关系到充电宝的使用寿命&#xff0c;更关…

【正点原子i.MX93开发板试用连载体验】项目计划和开箱体验

本文最早发表于电子发烧友&#xff1a;【   】【正点原子i.MX93开发板试用连载体验】基于深度学习的语音本地控制 - 正点原子学习小组 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com)https://bbs.elecfans.com/jishu_2438354_1_1.html 有一段时间没有参加电子发…

clickhouse-jdbc-bridge rce

clickhouse-jdbc-bridge 是什么 JDBC bridge for ClickHouse. It acts as a stateless proxy passing queries from ClickHouse to external datasources. With this extension, you can run distributed query on ClickHouse across multiple datasources in real time, whic…

支持向量机 (support vector machine,SVM)

支持向量机 &#xff08;support vector machine&#xff0c;SVM&#xff09; flyfish 支持向量机是一种用于分类和回归的机器学习模型。在分类任务中&#xff0c;SVM试图找到一个最佳的分隔超平面&#xff0c;使得不同类别的数据点在空间中被尽可能宽的间隔分开。 超平面方…

MMGPL: 多模态医学数据分析与图提示学习| 文献速递-基于深度学习的多模态数据分析与生存分析

Title 题目 MMGPL: Multimodal Medical Data Analysis with Graph Prompt Learning MMGPL: 多模态医学数据分析与图提示学习 01 文献速递介绍 神经学障碍&#xff0c;包括自闭症谱系障碍&#xff08;ASD&#xff09;&#xff08;Lord等&#xff0c;2018年&#xff09;和阿…

kafka的副本replica

指定topic的分区和副本 通过kafka命令行工具 kafka-topics.sh --create --topic myTopic --partitions 3 --replication-factor 1 --bootstrap-server localhost:9092 执行代码时指定分区个数

基于Spring Boot框架的EAM系统设计与实现

摘 要&#xff1a;文章设计并实现一个基于Spring Boot框架的EAM系统&#xff0c;以应对传统人工管理模式存在的低效与信息管理难题。系统利用Java语言、JSP技术、MySQL数据库等技术栈&#xff0c;构建了一个B/S架构的高效管理平台&#xff0c;提升了资产管理的信息化水平。该系…

大小端详解

引例 我们知道整形(int)是4个字节&#xff0c;例如随便举个例子&#xff1a;0x01020304&#xff0c;它一共占了四个地址位&#xff0c;01,02,03,04分别占了一个字节&#xff08;一个字节就对应了一个地址&#xff09;。 那么就会有个问题&#xff1a;我们的01到底是存储在高地…

STM32的 DMA(直接存储器访问) 详解

STM32的DMA&#xff08;Direct Memory Access&#xff0c;直接存储器存取&#xff09;是一种在单片机中用于高效实现数据传输的技术。它允许外设设备直接访问RAM&#xff0c;不需要CPU的干预&#xff0c;从而释放CPU资源&#xff0c;提高CPU工作效率&#xff0c;本文基于STM32F…

C++基础(1)

目录 C的输入输出&#xff1a; 命名空间域&#xff1a; 缺省&#xff08;默认&#xff09;参数&#xff1a; 函数重载&#xff1a; 引用&#xff1a; 内联函数inline&#xff1a; 指针空值nullptr&#xff1a; C的输入输出&#xff1a; 输入&#xff1a; int a; char …