文档章节

Java动态编译

 开着坦克的瑞兽
发布于 2017/05/14 16:54
字数 648
阅读 19
收藏 0

概述:

Java的动态编译就是在运行期直接编译.java文件,执行.class,并且能够获得相关的输入输出,甚至还能监听相关的事件。

步骤:

1、创建或自动生成.java文件

2、调用JavaCompiler获取编译器,该类允许开发人员编译java文件为class文件

     JavaCompiler compiler =ToolProvider.getSystemJavaCompiler();

3、获取文件管理器StandardJavaFileManager,用来管理要编译的.java文件。getStandardFileManager有3个参数,分别代表监听器、语言环境、字符集

     StandardJavaFileManager fileManger = compiler.getStandardFileManager(null, null, null);

4、获取表示给定文件的文件对象

   Iterable unils = fileManger.getJavaFileObjects(fileName)

5、获取编译任务的future接口CompilationTask,当调用它的call方法时,开始编译

  CompilationTask t = compiler.getTask(null, fileManger, null, null, null, unils);

  t.call();

6、调用URLClassLoader将编译的文件load内存,其中需要知道文件的位置,用URL记录,其中“file:/”表示本地文件。

     URL[] urls = new URL[]{new URL("file:/"+System.getProperty("user.dir")+"/scr")};

     URLClassLoader cl = new URLClassLoader(urls);

7、获取编译后的类

     Class c = cl.loadClass("com.chensr.util.function.Function");    

8、获取构造函数,构造方法如果有参数需要配置对应的参数类型

   Constructor constructor = c.getConstructor(String.class);

      Object b =constructor.newInstance("哈哈");

9、执行对应的方法

      Method method=c.getDeclaredMethod("方法名","参数类型"); 

      method.invoke(b,"参数值");

 

具体代码如下:

package com.chensr.util.function;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;


public class Reflection {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
        String str ="package com.chensr.util.function; \r\t"+                    
                    "public class Function { \r\t"+
                    "    public Function(String a) { \r\t"+
                    "         System.out.println(\"我是构造函数!\"+a);\r\t"+
                    "    }\r\t"+
                    "    public static void say(){ \r\t"+
                    "        System.out.println(\"我由string生成class\");\r\t"+
                    "    }\r\t"+
                    "}";
        
        //根据str生成.java文件
        String fileName=System.getProperty("user.dir")+
                        "\\src\\main\\java\\com\\chensr\\util\\function\\Function.java";
        System.out.println(fileName);
        File file = new File(fileName);
        FileWriter fw = new FileWriter(file);
        fw.write(str);
        fw.flush();
        fw.close();
        
        //调用JavaCompiler获取编译器,该类允许开发人员编译java文件为class文件
        JavaCompiler compiler =ToolProvider.getSystemJavaCompiler();
        //Java 标准文件管理器,第一个参数为监听器,第二个参数语音环境,第三个参数为字符集
        StandardJavaFileManager fileManger = compiler.getStandardFileManager(null, null, null);
        //获取表示给定文件的文件对象
        Iterable unils = fileManger.getJavaFileObjects(fileName);
        //CompilationTask表示编译任务的未来的接口。调用call()启动任务。getTask方法编译源代码,并将对应的class文件生成到指定目录
        CompilationTask t = compiler.getTask(null, fileManger, null, null, null, unils);
        t.call();
        fileManger.close();
        
        //load内存,并且创建一个实例
        URL[] urls = new URL[]{new URL("file:/"+System.getProperty("user.dir")+"/scr")};        
        URLClassLoader cl = new URLClassLoader(urls);
        Class c = cl.loadClass("com.chensr.util.function.Function");    
        //获取构造函数和执行对应的方法
        Constructor constructor = c.getConstructor(String.class);
        Object b =constructor.newInstance("哈哈");
        
        Method method=c.getDeclaredMethod("say"); 
        method.invoke(b);  
    }
}


 

© 著作权归作者所有

上一篇: 代理模式
粉丝 0
博文 3
码字总数 3259
作品 0
深圳
私信 提问
利用javax.tools动态编译执行java代码

 本文永久地址:https://my.oschina.net/bysu/blog/1552933 inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish )。   参考:使用 javax.tools 创建动态应用...

不最醉不龟归
2017/10/18
0
0
深度探讨Java字节代码的操纵方法

本文为IBM工程师成富编写的《Java深度历险》的第一部分Java字节代码的操纵,像这样Java语言的深度理解和运用还没有很多文章,我们把他奉献给读者,希望读者们喜欢。 51CTO编者按:我们曾给大...

mj4738
2011/11/02
0
0
Java Interface 是常量存放的最佳地点吗?

版权声明:本文为博主原创文章,欢迎大家讨论,未经博主允许不得转载. https://blog.csdn.net/u010398771/article/details/83509106 由于java interface中声明的字段在编译时会自动加上static ...

长河
2018/10/29
0
0
什么是Java语言?java语言简介

Java是由Sun Microsystems公司于1995年5月推出的Java程序设计语言(以下简称Java语言)和Java平台的总称。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态的W...

阿秀a
2010/10/19
0
0
Java深度理解——Java字节代码的操纵

导读:Java作为业界应用最为广泛的语言之一,深得众多软件厂商和开发者的推崇,更是被包括Oracle在内的众多JCP成员积极地推动发展。但是对于 Java语言的深度理解和运用,毕竟是很少会有人涉及...

刘学炜
2012/01/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

手把手教你写一个RPC

1.1 RPC 是什么 定义:RPC(Remote Procedure Call Protocol)——远程过程调用协议 ,RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC...

我最喜欢三大框架
34分钟前
0
0
系统监控-SpringBoot四大神器之Actuator

1. 为什么要使用Actuator来监控SpringBoot项目? 首先之前博客提到过使用JDK自带的JVM监控工具、Psi-Probe Tomcat监控工具以及Javamelody,也提到了Psi-Probe的强大,但是Psi-Probe针对jar包...

秋日芒草
36分钟前
5
0
pip通过setup.py和git仓库安装package

安装setup.py配置文件中的包 进入到setup.py所在目录 pip install -e . 1 安装git仓库中的包 pip install git+git clone 仓库地址.git 1 python代码打包为whl格式 python setup.py bdist_wh...

dillonxiao
37分钟前
4
0
SpringBoot系列教程JPA之基础环境搭建

JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Spring Data JPA是在 Hibernate 基础上封装的一款框架。JPA作为标准,实际上并没...

小灰灰Blog
38分钟前
3
0
聊聊dubbo的Invoker select

序 本文主要研究一下dubbo的Invoker select InvokerInvocationHandler.invoke dubbo-2.7.1-sources.jar!/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java public class InvokerIn......

go4it
42分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部