79动态编译与动态运行

scorpicat scorpicat     2023-04-30     472

关键词:

动态编译与动态运行

在这样的场景中:我们设计了一个网页,允许用户在网页上输入java代码,提交后获得java代码的执行结果。这个功能,无需用户安装jre或是jdk,就能获得java编译运行的结果。这个功能,就要依赖动态编译与动态运行。

这样设计:用户输入代码,提交后,通过网络流传入到我们的服务器,我们将流接受,转为对应的java文件,然后调用编译器编译它,再调用类加载器或是Runtime执行它对应的class文件,最后我们将执行后的结果,通过流返回给用户,完成功能。

那么这个过程中的:调用编译器与调用类加载器的过程,就是动态编译与动态运行的过程。

如何在程序中动态编译?

我们通过ToolProvider类获取JavaCompiler编译器工具,就可以对指定的文件进行编译。

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
			int result = compiler.run(null, null, null, "c:/myjava/HelloWorld.java");
			System.out.println(result==0?"编译成功":"编译失败");

  

需要注意的地方:run()方法前三个参数请参考本方法的api。第四个参数传入的时java文件的完整路径。方法返回的结果为0则编译成功,否则为编译失败。

如何在程序中动态运行class文件?

我们有两种方式可以动态加载class文件,它们分别是Runtime类与反射机制运行class文件对应的main方法。

Runtime类

每一个运行的程序都有一个对应的Runtime对象,我们可以通过Runtime.getRuntime()来获取它。通过这个对象,我们可以调用class文件获得一个进程(Process对象),这个进程执行不会显示在当前控制台(如果被加载的class有在控制台输出的语句的话)。但我们可以获得这个进程的标准输出流(一般值System.out,其它情况不知),可以将流导出到文件或是网络。

//动态运行
			Runtime runtime = Runtime.getRuntime();
			Process process = runtime.exec("java -cp c:/myjava HelloWorld");
			InputStream is = process.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String line = "";
			while(null!=(line = br.readLine())) 
				System.out.println(line);
			

  

需要注意的地方:exec()方法传入的是一个系统指令,这里我们传入的时“java -cp c:/myjava HelloWorld”,注意myjava与HelloWorld之间只有空格没有“/”符号,且类文件不加.class后缀。

标准输入与标准输出流

我不知道是否还存在其它标准输入输出流。

public static final InputStream in “标准”输入流。
public static final PrintStream out “标准”输出流。
InputStream is = System.in;
PrintStream ps = System.out;

反射机制加载class文件

利用反射机制我们可以更灵活的加载class文件,通过一个URL数组我们可以指定一个文件夹,然后使用URLClassLoader类获得类加载器,这个加载器可以加载指定文件夹中的任意一个类。加载的结果是得到这个class文件的Class对象(反射)。然后我们获取这个Class对象的main方法,执行main方法,技能加载这个class文件了。但是加载后似乎并没有对应的输出流...emmm

URL[] urls = new URL[] new URL("File:/c:/myjava/");
			URLClassLoader loader = new URLClassLoader(urls);
			Class c = loader.loadClass("HelloWorld");
			Method m = c.getMethod("main", String[].class);
			m.invoke(null, (Object)new String[] );//这里要注意!

  

注意:在调用invoke()方法时,传入的第一个参数为null,我也不知道为什么。第二个参数为该方法的实参列表,但是这个方法的形参是数组,那么在传入实参时,务必要强转为Object类型,否则会将数组中的元素拆分作为该方法的实参。

动态与静态函数库学习

...殊功能的运行。函数库依照是否被编译到程序内部而分为动态函数库与静态函数库。静态函数库特点扩展名(.a):这类函数库扩展名为libxxx.a类型。编译行为:这类函数库在编译的时候会直接整合到可执行程序中,所以利用静... 查看详情

如何mybatis中使用动态sql查询与注释

参考技术A  首先,楼主需了解何为动态sql,何为静态sql,这是他们的区别:  静态SQL:静态SQL语句一般用于嵌入式SQL应用中,在程序运行前,SQL语句必须是确定的,例如SQL语句中涉及的列名和表名必须是存在的。静态SQL语... 查看详情

编译型与解释型动态语言与静态语言强类型语言与弱类型语言的区别

(一)编译型语言和解释型语言  首先我们区分这样一个概念,编译型语言和解释型语言。我们编程用的都是高级型语言(写汇编和机器语言的除外),计算机只理解和运行机器语言,所以必须把高级语言翻译成机器语言计算... 查看详情

反射应用之动态代理

参考链接:http://blog.csdn.net/hejingyuan6/article/details/36203505动态代理与静态代理的区别静态:由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了(先编译生成.class字节码文件,... 查看详情

编译型语言解释型语言静态类型语言动态类型语言概念与区别

编译型语言和解释型语言1、编译型语言需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言。一般需经过编译(compile)、链接(linker)这两个步骤。编译是把源代码编译成机器码,链接是把各个模块的机器码... 查看详情

jvm方法的动态与静态绑定机制

...法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由JVM动态决定的;静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上在编译阶段就已经做了绑定;成员变量(... 查看详情

与动态库链接导致的可执行运行时崩溃

】与动态库链接导致的可执行运行时崩溃【英文标题】:Executableruntimecrashcausedbylinkingwithdynamiclibrary【发布时间】:2013-12-2016:28:02【问题描述】:堆栈:MIPS、Linux、C、C++使用GNU工具编译和链接(基于x86构建MIPS)公平警告:我是C... 查看详情

编译型语言解释型语言静态类型语言动态类型语言概念与区别

动态语言:修改结构;动态类型:运行时类型检查;编译语言:机器码、解释器;强类型:类型不可变。编译型语言和解释型语言1、编译型语言需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言。一般需经过... 查看详情

转载编译型语言解释型语言静态类型语言动态类型语言概念与区别

编译型语言和解释型语言1、编译型语言需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言。一般需经过编译(compile)、链接(linker)这两个步骤。编译是把源代码编译成机器码,链接是把各个模块的机器码... 查看详情

class.forname与动态加载

...方法创建一个类的类类型。不仅如此,这个方法还表示了动态加载类。动态加载类与静态加载类的区分:编译时刻加载的类称为静态加载类。运行时刻加载的类称为动态加载类。 静态加载的不足:在编译时就会把所有类都加... 查看详情

装载与动态链接

装载与动态链接1可执行文件的装载与进程可执行文件只有装载到内存后才能被CPU执行。早期的程序装载十分简陋,装载的基本过程就是把程序从外部存储器中读取到内存中的某个位置。历史有过的装载方式包括覆盖装载、页映... 查看详情

jvm方法的动态与静态绑定机制(代码片段)

...法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由JVM动态决定的;静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上在编译阶段就已经做了绑定;成员变量(... 查看详情

java之动态编译

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

qt如何实现静态编译与动态编译共存

我用的是4.8.4mingw版的库+Qtcreator,这样实现的是动态编译。我上网学静态编译,说要把qt库拿去静态编译,我按网上的说法做了,花了3小时多。而后打开Qtcreator发现以前的工程不能用了,会提示错误。于是新建一个工程再debug一... 查看详情

转:java动态编程(javassist研究)

概述什么是动态编程动态编程是相对于静态编程而言的,平时我们讨论比较多的就是静态编程语言,例如Java,与动态编程语言,例如JavaScript。那二者有什么明显的区别呢?简单的说就是在静态编程中,类型检查是在编译时完成的... 查看详情

linux下静态库动态库的创建与调用(代码片段)

...目开发时,经常会用到第三方库,也会自己创建动态库给别人或者给自己其他的工程项目使用。库的类型分为动态库、静态库。在Linux下动态库的后缀为.so,静态库的后缀为.lib。动态库称为共享库.程序在编译的时需... 查看详情

编译/运行时后的 Vue.js 动态图像路径

】编译/运行时后的Vue.js动态图像路径【英文标题】:Vue.jsDynamicImagepathsaftercompiling/runtime【发布时间】:2019-06-0520:12:05【问题描述】:我在使用Vue.js设置动态图像路径时遇到问题。我正在使用Vue-Cli来构建项目。我相信这个问题是... 查看详情

java静态代理和动态代理的区别

...接口增加方法,目标对象与代理对象都要进行修改。二、动态代理动态代理利用了JDKAPI,动态地在内存中构建代理对象,从而实现对目标对象的代理功能。动态代理又被称为JDK代理或接口代理。静态代理与动态代理的区别主要在... 查看详情