介绍
小编这次要给大家分享的是如何基于javassist进行动态编程,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。
今天在研究达博时,发现一个新的知识点,可以使用javassist包进行动态编程,hibernate也使用该包进行编程。晚上百度了很多资料,将它的特性以代码的形式展现出来。
包com.zhi.demo; 进口java.lang.reflect.Field; 进口javassist.ClassPool; 进口javassist.CtClass; 进口javassist.CtConstructor; 进口javassist.CtField; 进口javassist.CtMethod; 进口javassist.CtNewConstructor; 进口javassist.CtNewMethod; 进口javassist.Loader; 进口javassist.Modifier; 进口javassist.bytecode.AccessFlag;/* * * Javassist动态编程测试 * * @date 2019年03月11日23:00:33 * */公开课javassist { 公共静态void main (String [] args) { 尝试{ 测试(); }捕捉(异常e) { e.printStackTrace (); } } 私有静态空白测试()抛出异常{ System.out.println(“- - - - - - - - - - - - - - - - - - -新增类- - - - - - - - - - - - - - - - - -“); ClassPool池=ClassPool.getDefault ();//创建类 CtClass ct=pool.makeClass (“com.zhi.Person");//让类实现可克隆接口 ct。setInterfaces(新CtClass [] {pool.makeInterface (“java.lang.Cloneable")});//添加一个int类型的共有属性 CtField fieldId=new CtField (CtClass.intType“id", ct); fieldId.setModifiers (AccessFlag.PUBLIC); ct.addField (fieldId);//添加一个默认构造器 CtConstructor constructor1=CtNewConstructor.make(“公众人物(){this.id=1;}“, ct); ct.addConstructor (constructor1);//添加方法 CtMethod helloM=CtNewMethod 使(“公共空间你好(String des) {System.out.println(\“执行你好方法,\“+ des + \“,我的身份证是\“+ this.id);}“, ct); ct.addMethod (helloM);//将生成的. class文件保存到磁盘 ct.writeFile ();//加载目标类,可用ct.toClass()或新的装载机(池).loadClass () Class<及# 63;比;clazz=ct.toClass ();//Class<及# 63;比;clazz=new装载机(池).loadClass (“com.zhi.Person");//输出类基本信息 System.out.println(“包名:“;+ clazz.getPackageName ()); System.out.println(“类名:“;+ clazz.getName ()); System.out.println(“简要类名:“+ clazz.getSimpleName ()); System.out.println(“限定符:“;+ Modifier.toString (clazz.getModifiers ())); System.out.println(“继承类:“;+ clazz.getSuperclass () . getname ()); ?[]字段clazz.getDeclaredFields (); (字段字段:字段){ System.out.println(“属性名称:“+ field.getName() +“,属性类型:“+ field.getType() +“限定符:“ + Modifier.toString (field.getModifiers ())); }//构造一个对象,并执行你好方法 .newInstance对象ob=clazz.getDeclaredConstructor () (); clazz.getMethod (“hello" String.class)。调用(ob,“张三“);//解冻(执行toClass后会自动冻结) ct.defrost (); System.out.println(“- - - - - - - - - - - - - - - - - - -修改类- - - - - - - - - - - - - - - - - -“);//添加一个字符串类型的私有属性 CtField fieldName=new CtField (pool.get (String.class.getName ()),“name", ct); fieldName.setModifiers (AccessFlag.PRIVATE); ct.addField(字段名);//添加带参的构造函数 CtConstructor constructor2=new CtConstructor(新CtClass [] {pool.get (String.class.getName ())}, ct); constructor2.setModifiers (Modifier.PUBLIC); constructor2.setBody (“{this.name=1美元;}“); ct.addConstructor (constructor2); ct.addMethod (CtNewMethod.make(“公共空setName(字符串名称){this.name=名字;}“,ct)); ct.addMethod (CtNewMethod.make(“公共字符串getName(){返回this.name;}“, ct)); ct.writeFile ();//加载类,若前面已用ct.toClass()进行加载,则这里不能再用ct.toClass()加载,否则会出错,同一个加载不能2次加载同一个类 clazz=new装载机(池).loadClass (“com.zhi.Person"); 字段=clazz.getDeclaredFields (); (字段字段:字段){ System.out.println(“属性名称:“+ field.getName() +“,属性类型:“+ field.getType() +“限定符:“ + Modifier.toString (field.getModifiers ())); } ob=clazz.getDeclaredConstructor (String.class) .newInstance(“马云“); System.out.println(“执行getName方法得到的值为:“+ clazz.getMethod (“getName") .invoke (ob)); } }
执行上面代码输出结果为:
- - - - - - - - - - - - - - - - - - -新增类- - - - - - - - - - - - - - - - - - 包名:com.zhi 类名:com.zhi.Person 简要类名:人 限定符:公众 继承类:java . lang . object 属性名称:id,属性类型:int,限定符:公众 执行你好方法,张三,我的身份证是1 - - - - - - - - - - - - - - - - - - -修改类- - - - - - - - - - - - - - - - - - 属性名称:id,属性类型:int,限定符:公众 属性名称:名称,属性类型:以类,限定符:私有的 执行getName方法得到的值为:马云如何基于javassist进行动态编程