@TOCjava 之动态生成类

最近遇到一个需求,要求属性字段是可以前端动态编辑,然后要求导入导出的数据列要同步属性字段。导入导出功能不想自己写,想要集成好的现成工具。可是他是通过类注解获取属性的, 然鹅我的属性是动态的,不可能提前写好,这可怎么办呢。。。!于是就开始研究是不是可以动态创建类文件,于是乎经过一番战痘,查阅大量网上前备们的文献资资料,总结测试。。。好像可以也(^-^)V

取之与群众,传之与群众

package test;import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;/*** desc:自定义的类加载器,用于实现类的动态加载*/
public class MyClassLoader extends ClassLoader {//回车加换行符public String rt = "\r\n";//生成类的源文件,写成字符串的形式public String src ="package test;"+"public class HelloWorld  {" + rt +"    public String name;" + rt +"    public static void main(String[] args) {" + rt +"         System.out.println(\"Hello world!\");" + rt +"    }" + rt +"    public String getName() {" + rt +"      return this.name; " + rt +"    }" + rt +"    public void setName(String name) {" + rt +"      this.name = name;" + rt +"    }" + rt +"}";//类路径 F:/java/code/j2es/out/production/j2es/private String classPath;//类名 类的全限定包名 不带后缀  例如com.test.Noticeprivate String className = "test.HelloWorld";//class文件路径 F:/java/code/j2es/out/production/j2es/test/HelloWorld.classprivate final String classPackageName;//java文件路径 F:/java/code/j2es/out/production/j2es/test/HelloWorld.javaprivate final String javaPackageName;public MyClassLoader(){classPath = Objects.requireNonNull(MyClassLoader.class.getClassLoader().getResource("")).getPath();//获取编译后class文件所在的路径classPath = !classPath.startsWith("/")?classPath:classPath.substring(1);//获取出来的前面会有一个/,去掉前面的/System.out.println(classPath);String packageName = classPath + className.replace(".",File.separator);//类名转换路径classPackageName = packageName + ".class";javaPackageName = packageName + ".java";}public MyClassLoader(String src,String classPath,String className){this.src = src;this.classPath = classPath;this.className = className;String packageName = classPath + className.replace(".",File.separator);//类名转换路径classPackageName = packageName + ".class";javaPackageName = packageName + ".java";}/*** 指定的类的class文件是否存在* @return boolean*/private boolean isClassExist() {return FileUtil.isFileExist(classPackageName);}/*** 指定的类java文件是否存在* @return boolean*/private boolean isJavaExist(){return FileUtil.isFileExist(javaPackageName);}/*** 写文件*/private void writerFile() throws IOException {File file = new File (javaPackageName);FileWriter fw = new FileWriter (file);fw.write(src);fw.flush();fw.close();}/*** 编译java类* 使用rt.jar中的javax.tools包提供的编译器*/private void compiler(){JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager sjfm = compiler.getStandardFileManager (null, null, null);Iterable<? extends JavaFileObject> units = sjfm.getJavaFileObjects (javaPackageName);JavaCompiler.CompilationTask ct = compiler.getTask (null, sjfm, null, null, null, units);ct.call();}/*** 复写父类的类加载方法* @param name 类的全限定包名 不带后缀  例如com.test.Notice  而不要写成com.test.Notice.java* @return Class*/@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {//加载类的字节码byte[] classBytes;try {classBytes = Files.readAllBytes(Paths.get(classPackageName));} catch (IOException e) {throw new RuntimeException(e);}Class<?> clazz;//将字节码交给JVMclazz = defineClass(name,classBytes,0,classBytes.length);if(clazz == null){throw new ClassNotFoundException(name);}return clazz;}/*** 动态编译一个java源文件并加载编译生成的class*/public Class<?> dynamicLoadClass() throws ClassNotFoundException, IOException {//1、先将字符串源码写入java文件writerFile();//2、将java文件编译成class文件compiler();//3、把编译好的的交给JVMClass<?> clazz = findClass(className);//得到类后把java源码文件删掉if(isJavaExist()){if(!FileUtil.deleteFile(javaPackageName)){System.out.println("删除源文件失败!");}}return clazz;}public static void main (String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {MyClassLoader myClassLoader = new MyClassLoader();Class<?> clazz = myClassLoader.dynamicLoadClass();System.out.println(clazz);// 生成对象Object obj = clazz.newInstance();System.out.println(obj);// 调用main方法Method m = clazz.getMethod("main",String[].class);Object invoke = m.invoke(obj, new Object[] { new String[] {} });System.out.println(invoke);//调用setNameMethod m2 = clazz.getMethod("setName",String.class);Object invoke2 = m2.invoke(obj,"zhangsan");System.out.println(invoke2);//getNameMethod m1 = clazz.getMethod("getName");Object invoke1 = m1.invoke(obj);System.out.println(invoke1);}
}

何为传承

前面的人学会了,就要传授给后面的人,否则学而不传矢道也,知识得到传承才能开花和升华,名族才能强大

本文可以随意转载

java 之动态生成类相关推荐

  1. Java动态生成类以及动态添加属性 本篇文章来源于 Linux公社网站(www.linuxidc.c

    2019独角兽企业重金招聘Python工程师标准>>> 有个技术实现需求:动态生成类,其中类中的属性来自参数对象中的全部属性以及来自参数对象propertities文件. 那么技术实 ...

  2. 【java】Java运行时动态生成类几种方式

    1.概述 转载:Java运行时动态生成类几种方式 这里发现自己不知道的,原来Java 还能自己编译自己,学到了. 最近一个项目中利用规则引擎,提供用户拖拽式的灵活定义规则.这就要求根据数据库数据动态生 ...

  3. C#强化系列文章五:动态代码的使用(反射和动态生成类)

    在软件开发尤其是框架和底层开发时,为了更灵活的控制代码,常常需要进行一些动态的操作.比如根据用户的输入等动态的调用类中的方法或者根据数据库表结构.用户要求动态的生成一些类,然后再动态的调用类中的方法. ...

  4. 使用Eclipse UML 插件 Papyrus由Java代码反向生成类图

    使用Eclipse UML 插件 Papyrus由Java代码反向生成类图 为了补充上一篇博文(Java基础(复习三) -- 类图例子)类图的例子寻找一个可以生成类图的工具,搜索了若干文章后决定使用P ...

  5. 动态生成类_springboot动态生成类属性

    利用动态代理实现类中属性的动态生成. 使用场景:当不确定返回类中字段个数时,可使用动态生成属性个数实现需求.  注意:由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理. 引 ...

  6. Java之动态代理类实现日志简单实例

    开心一笑 上课呢,同桌撕了一片纸放嘴里了咬了咬,又吐回了手里. 揉了揉,揉成个球状,然后又把这东西给放嘴里,咽下去了. 我问:你干嘛呢? 这二货幽幽地说:这两天有点感冒,捏个药丸吃. 视频教程 大家好 ...

  7. unity 动态生成类_Houdini城市道路模型生成

    备注:第一篇文章被系统删了,很气,就更新了一张图,然后就被封号了,文章也被系统删了.所以现在只能新开文章,重新写了,先立个标题. 所以本篇算是一种重置版,加了一些最新进度和效果,上一篇文章是8月底写的 ...

  8. java swing 动态生成表格_6 个曾经牛逼哄哄的 Java 技术,你用过吗?

    大家好啊,今天给大家分享下我的开发历程中,我知道的那些被淘汰的技术或者框架,有些我甚至都没有用过,但我知道它曾经风光过. 废话不多说,下面我要开始吹了-- 1.Swing 下面这个是用 swing 开 ...

  9. 用Enterprise Architect从Java源码生成类图

    1.project---new project 建立工程,会弹出配置框,选择要包含的图形,只是分析代码结构,选择'class'类图即可(如下图),完成工程建立. 2.在右侧Project Browse ...

最新文章

  1. 110万开发者的福音,百度Easy DL商品检测专业版上线
  2. 跳跃游戏(判断是否可以跳到最后一个下标)
  3. Html做弹出式菜单,JavaScript制作的可折叠弹出式菜单示例
  4. Dubbo入门实例--转载
  5. golang浮点型及使用细节
  6. 2.函数(代码的整洁之道)
  7. Oauth 2.0概述
  8. [你必须知道的.NET]第十七回:貌合神离:覆写和重载
  9. MySQL Cluster7.2.4 集群配置
  10. python中的corr函数_Python中的相关分析correlation analysis的实现
  11. Confluence与Jira安装及后期迁移问题记录
  12. input中name和id的区别
  13. C++ 基于凸包的Delaunay三角网生成算法
  14. 安装sql server出现配置系统未能初始化
  15. 产品经理听完《等你下课》心态崩了?选择汇新云重振旗鼓
  16. lambda表达式最实用的例子,最实用的案例
  17. 图解最短路径之迪杰斯特拉算法(Java实现)
  18. 遇到这样的事,是挺难受的
  19. Mac设计的必备设计软件,看看你还差什么
  20. Tools/Profiler

热门文章

  1. 负雪明烛开通公众号啦~ 欢迎关注「负雪明烛」
  2. java pdf转图片原理_pdf转图片程序(java实现)
  3. Linux防止stack缓冲区溢出的有效方法
  4. 解救小哈——DFS算法举例
  5. SAP HANA XS ODATA使用参数展示具体数据
  6. 计算机快捷键大全列表6,常用的快捷键大全(IT)
  7. oracle mysql迁移方案_Oracle/云MySQL/MsSQL“大迁移”真相及最优方案
  8. 请不要在“微服务”的狂热中迷失自我!
  9. 计算机共享的媒体设备,多台计算机、手机和平板电脑中共享对文件和媒体的访问时怎么做...
  10. 【笔记】《Python数据分析与实战挖掘》