通过Java动态生成class文件

今天说下JAVA中的动态编译,这个功能根据我现在的了解好像没有见到过用的,我Jio的吧,现在的一些在线代码编缉器可以用到了,这个具体我也不是很清楚。感兴趣的大家可以自已了解下。

说到动态编缉大家可能会想到,动态编缉肯定不是像我们平时运行程序似的在本地的平台就开始编译了。

动态编译其实是在程序的运行过程中对Java文件的编译或者是运行.class的文件。比如说我今天想装一波,我写个java的程序,又写了个另一个java的程序在小伙伴面秀,我只运行一个java程序可以编译另一个java并且运行它。

我们先来了解下,在JAVA的6.0版本java开始引入的动态编译这个功能。其实在java6.0以前java也可以使用动态编译,那个时候好像是用的RunTime来实现的,感兴趣的可以了解下

我们先来说下6.0以后是如何进行动坊编译的呢?

这个时候JAVA引入了JavaCompiler,这个类主要是在程序中调用JAVA编程语言的接口,这个类是没有构造函数的,是接收的ToolsProvider类下的静态函数 getSystemJavaCompiler(),这个函数的主要功能获得此平台提供的Java编程语言编译器。

下面我们看下代码是如何编写的:

 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if(compiler == null){
       System.out.println("没有得到初始化");
       return;
}
int restuld =  compiler.run(null,null,null,"D:/myjava/HelloWorld.java");
System.out.println(restuld == 0 ? "编译成功":"编译失败");

这里我来说下这里是什么意思,第一行代码是获得JAVA的编程语言的编译器,第二行是一个判空处理,这里行记得加上,小编在这里遇到了问题卡了10多分钟,我也不知道怎么回事系统没有获取到java语言的编译器,一直 报出空指针异常的问题,我寻找了好久最后加了个判空处理发现这里是空的,后来我也没有处理多运行了几次就好了,如果有朋友发现这里是怎么回事评论下的,第6行代码大家可以理解为是在进行编译java源码程序。这里有4个参数分别是:

  • 为java编译器提供参数
  • 得到java编译的输出信息
  • 接收编译的错误
  • 可变参数能传入一个或多个java源码

  

这里的返回值是如果编译成功返回的是0,编译失败返回非0.

大家可以看下面这张API的截图,可以了解下,

经过程序的运行,我成功的得到了一个HelloWorld.class文件,到这里大家先练习下上面的代码,下面部分是关于如何通过反射来执行编译生成的类。

通过反射来运行生成的Class类

讲到这里我们先来了解下URLClassLoader,这个是类加载器,在我们是用类加载器的时候构造参数是可以传入一个url数组,

我们需要讲类文件的url放到一个Url数组中,可以通过创建url数组包裹url的方式来创建一个url数组,例:

URL[] urls = new URL[]{new URL("file:/" + "D:/myjava/")};

这里new Url的时候不了解的小伙伴可以看下JAVA的API文档url有一个构造参数是传入的一个路径,这个路径是要带上协议的,比如我要加载文件我就要带上file协议,如果找不到协议可能会发生格式错误的异常。

这里的url参数是可以填写目录的,接下来我们要构造一个类加载器(URLClassLoader)可以通过这个类加载器加载我们上面生成的类。

URLClassLoader loader = new URLClassLoader(urls);

使用默认委托父级ClassLoader为指定的URL构造一个新的ClassLoader 。 在首次搜索父类加载器后,将按照为类和资源指定的顺序搜索URL。 任何以“/”结尾的URL都假定是指一个目录。 否则,URL被认为是指根据需要下载并打开的JAR文件。 接下来我们要开始加载生成的类文件了:

Class c = loader.loadClass("HelloWorld");

看到这里相比大家应该很熟悉了吧,这里和我上次给大家说的反射类似,这里拿到了一个class的对象,我们可以通过class的对象查找方法,

Method method = c.getMethod("main",String[].class);

我这里就和大家大概的说下因为我在反射的那篇博客和大家说了,这里就不详细的讲解了,这里填的两个参数的意思是,参数一:是我们要查找的方法名,参数二:是方法的参数类型,在main方法的参数列表里都会有一个String数组类型的参数,主要是接受在命令行工具下填写的参数的。通过这行命令我们拿到了一个方法。接下来开始通过invoke方法你可以理解成调用这个方法:

method.invoke(null,(Object)new String[]{});

这里我们在反射那讲说要填写一个对象,这里我们填写空就可以了,因为在java的main方法是静态的,所以可以直接调用,

这样就可以运行一个类啦,

不上反射的教程,传送门

JAVA之动态编译的更多相关文章

  1. 深入理解Java的动态编译

    前提 笔者很久之前就有个想法:参考现有的主流ORM框架的设计,造一个ORM轮子,在基本不改变使用体验的前提下把框架依赖的大量的反射设计去掉,这些反射API构筑的组件使用动态编译加载的实例去替代,从而可 ...

  2. Java的动态编译、动态加载、字节码操作

    想起来之前做的一个项目:那时候是把需要的源代码通过文件流输出到一个.java文件里,然后调用sun的Comipler接口动态编译成.class文件,然后再用专门写的一个class loader加载这个 ...

  3. Java程序动态编译Java源文件

    最近接触到公司一个项目,需要将生成的源码动态编译,记录下学习过程. 先贴出官网推荐写法: JavaCompiler.CompilationTask getTask(Writer out,        ...

  4. 动态生成java、动态编译、动态加载

    我曾经见过一个“规则引擎”,是在应用系统web界面直接编写java代码,然后保存后,规则即生效,我一直很是奇怪,这是如何实现的呢?实际这就好像jsp,被中间件动态的编译成java文件,有被动态的编译成 ...

  5. JAVA中动态编译的简单使用

    一.引用库 pom文件中申明如下: <dependencies> <!-- https://mvnrepository.com/artifact/junit/junit --> ...

  6. java动态编译笔记

    1 前言 Java的动态编译知识,真真在实际开发中并不是经常遇到.但是学习java动态编译有助于我们从更深一层次去了解java.对掌握jdk的动态代理模式,这样我们在学习其他一些开源框架的时候就能够知 ...

  7. [改善Java代码]慎用动态编译

    建议17: 慎用动态编译 //=========这篇博文暂时理解不透......... 动态编译一直是Java的梦想,从Java 6版本它开始支持动态编译了,可以在运行期直接编译.java文件,执行. ...

  8. (转载)JAVA动态编译--字节代码的操纵

    在一般的Java应用开发过程中,开发人员使用Java的方式比较简单.打开惯用的IDE,编写Java源代码,再利用IDE提供的功能直接运行Java 程序就可以了.这种开发模式背后的过程是:开发人员编写的 ...

  9. Java动态编译

    程序产生过程 下图展示了从源代码到可运行程序的过程,正常情况下先编译(明文源码到字节码),后执行(JVM加载字节码,获得类模板,实例化,方法使用).本文来探索下当程序已经开始执行,但在.class甚至 ...

随机推荐

  1. 【LeetCode-easy】Merge Two Sorted Lists

    思路:指针p用于串联怎个链表,比较两个指针的大小,连接较小的一个.如果一个链表到达链尾,连接另外一个链表余下来的所以节点. public ListNode mergeTwoLists(ListNode ...

  2. 冷门PHP函数汇总

    概述 整理一些日常生活中基本用不到的PHP函数,也可以说在框架内基本都内置了,无需我们去自行使用的函数.量不多.后续在日常开发中如遇到更多的冷门,会更新本文章 sys_getloadavg 获取系统的 ...

  3. 20145239杜文超 《Java程序设计》第4周学习总结

    20145239 <Java程序设计>第4周学习总结 教材学习内容总结 第六章: 继承:避免多个类间重复定义共同行为.即当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多 ...

  4. SPOJ - REPEATS —— 后缀数组 重复次数最多的连续重复子串

    题目链接:https://vjudge.net/problem/SPOJ-REPEATS REPEATS - Repeats no tags  A string s is called an (k,l ...

  5. linux shell发送邮件

    我的系统环境: [root@NPS-JK ~]# cat /etc/issue Red Hat Enterprise Linux Server release 6.1 (Santiago) Kerne ...

  6. centos7 永久修改主机名

    hostnamectl set-hostname xxx 一劳永逸,永绝后患

  7. Sturs2 -概念讲解 第一弹

    源码下载地址:http://struts.apache.org/ struts-2.5.14.1-all.zip --所有内容 struts-2.5.14.1-apps.zip  --实例的应用 st ...

  8. 002-CSS基础

    1 CSS和文档 CSS 层叠样式表 元素 每个元素都会生成一个框(box) 元素 = 替换元素 + 非替换元素 替换元素 显示的内容是元素内的某个属性而不是元素本身, 如img 非替换元素 大部分类 ...

  9. python-while循环,for ,以及字符串格式化

    1.字符串格式化 name="suwukong" print("欢迎",name,"光临")print("欢迎 "+na ...

  10. P1955 [NOI2015]程序自动分析[离散化+并查集]

    大水题一道,不明白为什么你谷评了个蓝.一看就是离散化,先去满足相等的条件,相等即为两点联通,或者说在同一个集合内.再看不相等,只有两元素在同一集合才不满足.裸的disjoint-set直接上,常数巨大 ...